Definition of curry :
curry :: ((a, b) -> c) -> a -> b -> c curry f = \xy -> f (x, y)
If you substitute this in:
\xyz -> (curry (==) xy) z \xyz -> ((==) (x, y)) z -- Function application \xyz -> (==) (x, y) z -- Remove parentheses (function application is left associative in Haskell, so they are unnecessary here) \xyz -> (x, y) == z -- Convert to infix
We can immediately say that z must be some kind of tuple, otherwise this last line will not introduce a check, since both == arguments must be of the same type.
When we look at the definition of an instance of a tuple for Eq , we find
instance (Eq a, Eq b) => Eq (a, b) where (x, y) == (x', y') = (x == x') && (y == y')
(This is not indicated in the source code of the standard library, it actually uses the "offline output" mechanism to automatically obtain an instance for type (Eq a, Eq b) => (a, b) . This code is equivalent to what is obtained.)
So, in this case, we can consider == as if it had type
(==) :: (Eq a, Eq b) => (a, b) -> (a, b) -> Bool
Both x and y must have types that are instances of Eq , but they must not be the same instance of Eq . For example, what if we have 12 and "abc" ? These are two different types, but we can still use our function, since both of them are instances of Eq : (\xyz -> (x, y) == z) (12, "abc") (30, "cd") (this type of expression checks and evaluates to False ).