
On 26 Feb 2009, at 23:07, Philip Scott wrote:
Okay, thanks everyone for the help with the last question; I've got another one for you if you are keen. It's short and sweet.
You can easily define a lambda expression that takes a tuple - e.g. in ghci
let foo = \(x,y) -> 42 foo :: (t, t1) -> Integer
foo (5,5) 42
Yay. Now that isn't a very exciting function. Tt takes two anythings and gives you a nice meaningful number. Now let us say for some perverse reason I want to make a lambda to test for equality. That is, reimplement the functionality of (==) using, well, (==).
let foo2 = \(x,y) -> x == y
foo2 :: ((), ()) -> Bool
Uh-oh. Now things are getting a little odd. I am not entirely sure what that type signature means (I was expecting to see something about the types having to be the same and an instance of the Eq class but alas..) The function certainly doesn't do what I want it to:
foo2 (5,5)
No instance for (Num ()) arising from the literal `5' at <interactive>:1:6 Possible fix: add an instance declaration for (Num ()) In the expression: 5 In the first argument of `foo2', namely `(5, 5)' In the expression: foo2 (5, 5)
This is itself a stupid problem, but it is a distilled version of some trouble I was having writing a filter that works on a list of tuples. Any pointers or slaps in the face for being too stupid warmly welcomed. I have already tried my usual trick of smothering the thing parentheses but it appeared to be all in vain.
I'm not 100% certain here, so someone may correct me, but I think this is what's going on: foo2 has no arguments. Because of this, ghci makes it a CAF. At this point, the monomorphism restriction kicks in, and the CAF has to be monomorphic. ghc then chooses a type for it, and defaulting choses the most simple type it can find – () (this is the type that contains one value – () ). If instead, you do let foo3 (x,y) = x == y, you will get the type you expected. Another way to write it ofc would simply be uncurry (==). Bob