[Haskell-cafe] General function to count list elements?

Ryan Ingram ryani.spam at gmail.com
Sat Apr 18 12:51:46 EDT 2009


Haskell is referentially transparent.  This enables a whole host of
program reasoning and compiler optimization techniques that you can't
get in languages without this property; it's hard to explain why it is
good until you've been bitten by code that *isn't*.

One big consequence of referential transparency is that a whole host
of complicated optimizations in other languages are replaced with
simple inlining.

So one question is, what does this program do?
> main = print (count id [id])

The compiler might decide to inline the first id:
> main = print (count (\x -> x) [id])
which then, if we are comparing "machine addresses", means they are not equal.

I am sure you agree that code that stops working depending on the
optimization settings of the compiler is a scary thing!

In scheme, which is not referentially transparent, there are several
equality primitives.  One checks "object identity", whereas another
goes into the depths of any structure it is passed and compares the
innards.  In Haskell, there is *no* concept of "object identity.  It
just doesn't exist!   This means there is no observable difference
between 1 and (length [ "hello" ]).  There's no observable difference
between const and (\x y -> x).

In order to make this work, but still be able to use == (which
everyone wants), == requires its arguments to be of a type that is
comparable for equality; that's what the error message from ghci is
saying:

On Sat, Apr 18, 2009 at 9:27 AM, michael rice <nowgate at yahoo.com> wrote:
>     No instance for (Eq (a -> a -> Bool))
>       arising from a use of `==' at <interactive>:1:0-13

  -- ryan


More information about the Haskell-Cafe mailing list