Reputation: 127
I was manually writing a currying function in Haskell as follows.
curry f = \x y -> f(x,y)
Then I use this max(x, y) = if x > y then x else y
as f, and I wrote max1 = curry max
to get the curried function
But this is not allowed. Why is it wrong?
Upvotes: 1
Views: 538
Reputation: 68152
You ran into the dreaded monomorphism restriction, which limits where Haskell can infer polymorphic types.
A binding that does not "look" like a function—has no named arguments—cannot have a polymorphic type. The problem is that your max
function does have a polymorphic type (it works for any type o
that is in the Ord
class), which forces the type system to pick a single concerete orderable type for max1
. Since there is no default type to pick, it tells you a type variable is ambiguous.
There are three ways you can avoid this restriction. One, as you've already seen, is to make the arguments explicit, making the whole binding look like a function:
max1 x y = curry max x y
Another is to add an explicit type signature:
max1 :: Ord o => o -> o -> o
max1 = curry max
Finally, you can also turn off the restriction by adding a compiler directive to the top of your module:
{-# LANGUAGE NoMonomorphismRestriction #-}
Out of all of these, the most idiomatic choice is adding a type signature. Generally, every top-level name should have an explicit type signature. This is not mandatory, but is considered good style because, apart from avoiding monomorphism issues, it also helps catch more errors and makes error messages easier to read. If you turn on all the warnings in GHC (with the -Wall
flag), it will warn you about top-level names without type signatures.
Upvotes: 5