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

I know functions can be compared in Scheme Welcome to DrScheme, version 4.1 [3m]. Language: Swindle; memory limit: 128 megabytes.
(equal? equal? equal?) #t
but apparently not in Haskell
[michael@localhost ~]$ ghci
GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Prelude> (==) (==) (==)
<interactive>:1:0:
No instance for (Eq (a -> a -> Bool))
arising from a use of `==' at <interactive>:1:0-13
Possible fix: add an instance declaration for (Eq (a -> a -> Bool))
In the expression: (==) (==) (==)
In the definition of `it': it = (==) (==) (==)
Prelude>
though I'm new at Haskell and may not be posing the question properly.
I would think a language with 1st-class support for functions would
certainly include comparing them.
To compare two functions in C, I would compare their machine addresses.
Michael
--- On Sat, 4/18/09, Eugene Kirpichov
Though I haven't tried it out, it's trying to use my function to count functions.
The first argument is the identity function.
The second argument is a list of a different form of the identity function.
Though the two identity functions, given the same input, would produce the same output, I doubt they would be equal.
So my guess at an answer would be zero.
Michael
--- On Sat, 4/18/09, Eugene Kirpichov
wrote: From: Eugene Kirpichov
Subject: Re: [Haskell-cafe] General function to count list elements? To: "michael rice" Cc: haskell-cafe@haskell.org Date: Saturday, April 18, 2009, 11:03 AM What should
count (\x -> x) (replicate 10 (\y -> if 1==1 then y else undefined))
return?
2009/4/18 michael rice
: Is there a general function to count list elements. I'm trying this
count :: a -> [a] -> Int count x ys = length (filter (== x) ys)
with this error upon loading
=============
[michael@localhost ~]$ ghci count GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. [1 of 1] Compiling Main ( count.hs, interpreted )
count.hs:2:29: Could not deduce (Eq a) from the context () arising from a use of `==' at count.hs:2:29-32 Possible fix: add (Eq a) to the context of the type signature for `count' In the first argument of `filter', namely `(== x)' In the first argument of `length', namely `(filter (== x) ys)' In the expression: length (filter (== x) ys) Failed, modules loaded: none. Prelude>
=============
Not sure what it's trying to tell me other than I need an (Eq a) somewhere.
Michael
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Eugene Kirpichov Web IR developer, market.yandex.ru
-- Eugene Kirpichov Web IR developer, market.yandex.ru

2009/4/18 michael rice
I know functions can be compared in Scheme
Welcome to DrScheme, version 4.1 [3m]. Language: Swindle; memory limit: 128 megabytes.
(equal? equal? equal?) #t
That's not the functions being compared, but the memory addresses of the code implementing them. If your goal is comparing functions to answer a question "Are these two values indistinguishable?", equal? doesn't help you, because it may answer 'false' even if these two values are indistinguishable from a mathematical point of view.
but apparently not in Haskell
[michael@localhost ~]$ ghci GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> (==) (==) (==)
<interactive>:1:0: No instance for (Eq (a -> a -> Bool)) arising from a use of `==' at <interactive>:1:0-13 Possible fix: add an instance declaration for (Eq (a -> a -> Bool)) In the expression: (==) (==) (==) In the definition of `it': it = (==) (==) (==) Prelude>
though I'm new at Haskell and may not be posing the question properly.
I would think a language with 1st-class support for functions would certainly include comparing them.
Again, this is first-class support for memory addresses of code representing functions.
To compare two functions in C, I would compare their machine addresses.
Why would you need that at all?
Michael
--- On Sat, 4/18/09, Eugene Kirpichov
wrote: From: Eugene Kirpichov
Subject: Re: [Haskell-cafe] General function to count list elements? To: "michael rice" Cc: haskell-cafe@haskell.org Date: Saturday, April 18, 2009, 11:39 AM Could you then provide an example of two functions that *are* equal, or, even better, a definition of equality for arbitrary functions? Since Haskell may be compiled into C, this must be a definition that is implementable in C.
2009/4/18 michael rice
: Though I haven't tried it out, it's trying to use my function to count functions.
The first argument is the identity function.
The second argument is a list of a different form of the identity function.
Though the two identity functions, given the same input, would produce the same output, I doubt they would be equal.
So my guess at an answer would be zero.
Michael
--- On Sat, 4/18/09, Eugene Kirpichov
wrote: From: Eugene Kirpichov
Subject: Re: [Haskell-cafe] General function to count list elements? To: "michael rice" Cc: haskell-cafe@haskell.org Date: Saturday, April 18, 2009, 11:03 AM What should
count (\x -> x) (replicate 10 (\y -> if 1==1 then y else undefined))
return?
2009/4/18 michael rice
: Is there a general function to count list elements. I'm trying this
count :: a -> [a] -> Int count x ys = length (filter (== x) ys)
with this error upon loading
=============
[michael@localhost ~]$ ghci count GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. [1 of 1] Compiling Main ( count.hs, interpreted )
count.hs:2:29: Could not deduce (Eq a) from the context () arising from a use of `==' at count.hs:2:29-32 Possible fix: add (Eq a) to the context of the type signature for `count' In the first argument of `filter', namely `(== x)' In the first argument of `length', namely `(filter (== x) ys)' In the expression: length (filter (== x) ys) Failed, modules loaded: none. Prelude>
=============
Not sure what it's trying to tell me other than I need an (Eq a) somewhere.
Michael
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Eugene Kirpichov Web IR developer, market.yandex.ru
-- Eugene Kirpichov Web IR developer, market.yandex.ru
-- Eugene Kirpichov Web IR developer, market.yandex.ru

Hello michael, Saturday, April 18, 2009, 8:27:45 PM, you wrote: so you can use Scheme to derive theorem proofs. useful for exams! :)
I know functions can be compared in Scheme
Welcome to DrScheme, version 4.1 [3m]. Language: Swindle; memory limit: 128 megabytes.
(equal? equal? equal?) #t
but apparently not in Haskell
[michael@localhost ~]$ ghci GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude>> (==) (==) (==)
<interactive>:1:0: No instance for (Eq (a -> a -> Bool)) arising from a use of `==' at <interactive>:1:0-13 Possible fix: add an instance declaration for (Eq (a -> a -> Bool)) In the expression: (==) (==) (==) In the definition of `it': it = (==) (==) (==) Prelude>>
though I'm new at Haskell and may not be posing the question properly.
I would think a language with 1st-class support for functions would certainly include comparing them.
To compare two functions in C, I would compare their machine addresses.
Michael
--- On Sat, 4/18/09, Eugene Kirpichov
wrote:
From: Eugene Kirpichov
Subject: Re: [Haskell-cafe] General function to count list elements? To: "michael rice" Cc: haskell-cafe@haskell.org Date: Saturday, April 18, 2009, 11:39 AM
Could you then provide an example of two functions that *are* equal, or, even better, a definition of equality for arbitrary functions? Since Haskell may be compiled into C, this must be a definition that is implementable in C.
2009/4/18 michael rice
: Though I haven't tried it out, it's trying to use my function to count functions.
The first argument is the identity function.
The second argument is a list of a different form of the identity function.
Though the two identity functions, given the same input, would produce the same output, I doubt they would be equal.
So my guess at an answer would be zero.
Michael
--- On Sat, 4/18/09, Eugene Kirpichov
wrote: From: Eugene Kirpichov
Subject: Re: [Haskell-cafe] General function to count list elements? To: "michael rice" Cc: haskell-cafe@haskell.org Date: Saturday, April 18, 2009, 11:03 AM What should
count (\x -> x) (replicate 10 (\y -> if 1==1 then y else undefined))
return?
2009/4/18 michael rice
: Is there a general function to count list elements. I'm trying this
count :: a -> [a] -> Int count x ys = length (filter (== x) ys)
with this error upon loading
=============
[michael@localhost ~]$ ghci count GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. [1 of 1] Compiling Main ( count.hs, interpreted )
count.hs:2:29: Could not deduce (Eq a) from the context () arising from a use of `==' at count.hs:2:29-32 Possible fix: add (Eq a) to the context of the type signature for `count' In the first argument of `filter', namely `(== x)' In the first argument of `length', namely `(filter (== x) ys)' In the expression: length (filter (== x) ys) Failed, modules loaded: none. Prelude>
=============
Not sure what it's trying to tell me other than I need an (Eq a) somewhere.
Michael
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Eugene Kirpichov Web IR developer, market.yandex.ru
-- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Also, having such an equality test will introduce ambiguity and
unsoundness, prevent the compiler from certain optimizations etc.
For example, should "(+5)==(+5)" be true or false? What about "let
f=(+5) in f==f"?
If you are declaring the first equality to be true, then you are
implying that the compiler must implement extensional equality, which
is impossible. Consider let x=5 in (+x)==(+x).
If you are declaring it to be false, then you are breaking referential
transparency: you can't anymore safely substitute "let x=v in E" with
E[x:=v].
C doesn't have these problems because it never declared that it has
any form of referential transparency or mathematical soundness;
neither does it have closures and currying.
Scheme explicitly declares that the result of equal? on functions
can't be relied upon.
Haskell takes the mathematically sound path: it simply outlaws ambiguities.
2009/4/18 michael rice
I know functions can be compared in Scheme
Welcome to DrScheme, version 4.1 [3m]. Language: Swindle; memory limit: 128 megabytes.
(equal? equal? equal?) #t
but apparently not in Haskell
[michael@localhost ~]$ ghci GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> (==) (==) (==)
<interactive>:1:0: No instance for (Eq (a -> a -> Bool)) arising from a use of `==' at <interactive>:1:0-13 Possible fix: add an instance declaration for (Eq (a -> a -> Bool)) In the expression: (==) (==) (==) In the definition of `it': it = (==) (==) (==) Prelude>
though I'm new at Haskell and may not be posing the question properly.
I would think a language with 1st-class support for functions would certainly include comparing them.
To compare two functions in C, I would compare their machine addresses.
Michael
--- On Sat, 4/18/09, Eugene Kirpichov
wrote: From: Eugene Kirpichov
Subject: Re: [Haskell-cafe] General function to count list elements? To: "michael rice" Cc: haskell-cafe@haskell.org Date: Saturday, April 18, 2009, 11:39 AM Could you then provide an example of two functions that *are* equal, or, even better, a definition of equality for arbitrary functions? Since Haskell may be compiled into C, this must be a definition that is implementable in C.
2009/4/18 michael rice
: Though I haven't tried it out, it's trying to use my function to count functions.
The first argument is the identity function.
The second argument is a list of a different form of the identity function.
Though the two identity functions, given the same input, would produce the same output, I doubt they would be equal.
So my guess at an answer would be zero.
Michael
--- On Sat, 4/18/09, Eugene Kirpichov
wrote: From: Eugene Kirpichov
Subject: Re: [Haskell-cafe] General function to count list elements? To: "michael rice" Cc: haskell-cafe@haskell.org Date: Saturday, April 18, 2009, 11:03 AM What should
count (\x -> x) (replicate 10 (\y -> if 1==1 then y else undefined))
return?
2009/4/18 michael rice
: Is there a general function to count list elements. I'm trying this
count :: a -> [a] -> Int count x ys = length (filter (== x) ys)
with this error upon loading
=============
[michael@localhost ~]$ ghci count GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. [1 of 1] Compiling Main ( count.hs, interpreted )
count.hs:2:29: Could not deduce (Eq a) from the context () arising from a use of `==' at count.hs:2:29-32 Possible fix: add (Eq a) to the context of the type signature for `count' In the first argument of `filter', namely `(== x)' In the first argument of `length', namely `(filter (== x) ys)' In the expression: length (filter (== x) ys) Failed, modules loaded: none. Prelude>
=============
Not sure what it's trying to tell me other than I need an (Eq a) somewhere.
Michael
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Eugene Kirpichov Web IR developer, market.yandex.ru
-- Eugene Kirpichov Web IR developer, market.yandex.ru
-- Eugene Kirpichov Web IR developer, market.yandex.ru

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
No instance for (Eq (a -> a -> Bool)) arising from a use of `==' at <interactive>:1:0-13
-- ryan

On 19 Apr 2009, at 4:27 am, michael rice wrote:
I know functions can be compared in Scheme
Welcome to DrScheme, version 4.1 [3m]. Language: Swindle; memory limit: 128 megabytes.
(equal? equal? equal?) #t
but apparently not in Haskell
I have a copy of R6RS somewhere, but I'll refer to R5RS. Section 6.1 says there are three equality predicates: eq? eqv? equal? (eqv? obj1 obj2) returns #t if "obj1 nd obj2 are procedures whose location-tags are equal", it returns #f if they "are procedures that would behave differently ... for some arguments." Section 4.1.4 says "Each procedure created as the result of evaluating a lambda expression is (conceptually) tagged with a storage location in order to make eqv? and eq? work on procedures." What this boils down to is that (let ((F (lambda (X) (list X X)))) (eqv? F F)) is defined to answer true and (let ((F (lambda (X) (list X X))) (G (lambda (X) (cons X X)))) (eqv? F G)) is defined to answer false. But the Scheme reports are very very careful to leave (let ((F (lambda (X) (list X X))) (G (lambda (X) (list X X)))) (eqv? F G)) *UN*defined except that it is some Boolean value. Applied to procedures, eq? and equal? are the same as eqv?. Scheme equality of procedures is not the same thing as mathematical equality of functions. Two mathematically equal functions may or may not compare equal in Scheme. And Scheme implementations may differ. For example, (let ((F (lambda (X) (list X X))) (G (lambda (X) (list X X)))) (eqv? F G)) *might* be optimised to #t, but then again, it *might* be optimised to #f, and both answers are "right" by R5RS. Haskell tries to be a little more defined than that (:-).
participants (5)
-
Bulat Ziganshin
-
Eugene Kirpichov
-
michael rice
-
Richard O'Keefe
-
Ryan Ingram