Thomas Davie tom.davie at gmail.com
Thu Feb 26 17:25:42 EST 2009

```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
```