Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does curry (==) work?

I understand that:

(==) :: Eq a => a -> a -> Bool

An example of application may be (==) 2 2, which result is True.

and that:

uncurry (==) :: Eq b => (b, b) -> Bool.

An example of application may be uncurry (==) (2, 2), which result is True.

But I don't understand and visualize an example why:

curry (==) :: (Eq a, Eq b) => a -> b -> (a, b) -> Bool

Any help?

Thanks,
Sebastián

like image 944
Fof Avatar asked Apr 22 '14 01:04

Fof


2 Answers

== can be used on tuples, that is you can write (a1, b1) == (a2, b2).

In that case the type of == is specialized to (Eq a, Eq b) => (a, b) -> (a,b) -> Bool.

If you now apply curry to that type, you get (Eq a, Eq b) => a -> b -> (a, b) -> Bool.

like image 62
sepp2k Avatar answered Nov 10 '22 14:11

sepp2k


The definition of curry is:

curry :: ((a, b) -> c) -> a -> b -> c
curry f = \x y -> f (x, y)

If we substitute that in:

\x y z -> (curry (==) x y) z
\x y z -> ((==) (x, y)) z    -- Function application
\x y z -> (==) (x, y) z      -- Remove parentheses (function application is left associative in Haskell, so they are unnecessary here)
\x y z -> (x, y) == z        -- Convert to infix

We can tell right away that z must be some kind of tuple as well, or else this last line wouldn't type check since both arguments of == must have the same type.

When we look at the definition of the tuple instance for Eq, we find

instance (Eq a, Eq b) => Eq (a, b) where
  (x, y) == (x', y') = (x == x') && (y == y')

(This isn't spelled out in the source code of the standard library, it actually uses the "standalone deriving" mechanism to automatically derive the instance for the (Eq a, Eq b) => (a, b) type. This code is equivalent to what gets derived though.)

So, in this case, we can treat == as though it has the type

(==) :: (Eq a, Eq b) => (a, b) -> (a, b) -> Bool

Both x and y must have types that are instances of Eq, but they don't need to be the same instance of Eq. For example, what if we have 12 and "abc"? Those are two different types but we can still use our function, since they are both instances of Eq: (\x y z -> (x, y) == z) (12, "abc") (30, "cd") (this expression type checks and evaluates to False).

like image 35
David Young Avatar answered Nov 10 '22 14:11

David Young