This code is from the book "Learn You a Haskell for Great Good!":
maximum' :: (Ord a) => [a] -> a
maximum' [] = error "maximum of empty list"
maximum' [x] = x
maximum' (x:xs)
| x > maxTail = x
| otherwise = maxTail
where maxTail = maximum' xs
It works fine on non-empty lists, but supplying an empty list:
main = print $ maximum' []
gives this compiler error:
Ambiguous type variable ‘a0’ arising from a use of ‘maximum'’ prevents the constraint ‘(Ord a0)’ from being solved.
Why is that? Shouldn't the code actually catch it when an empty list is supplied? I don't understand the error message.
Ambiguous type variable ‘a0’ arising from a use of ‘maximum'’ prevents the constraint ‘(Ord a0)’ from being solved.
This means that when you call maximum' []
, the type of []
is not clear: it could be [Int]
or [()]
or something else.
In this particular case, the result happens to be the same for different types of the list. The compiler can't prove it here, and in general that's not the case. Consider this function:
readAndPrepend :: (Read a, Show a) => String -> [a] -> String
readAndPrepend s xs = show (read s : xs)
If you call readAndPrepend "42" []
, it's ambiguous what the result should be:
ghci> readAndPrepend "42" ([] :: [Int])
"[42]"
ghci> readAndPrepend "42" ([] :: [Double])
"[42.0]"
ghci> readAndPrepend "42" ([] :: [()])
"[*** Exception: Prelude.read: no parse
ghci>
In other words, the a
type variable is "unsolved", like a free x
in a mathematical equation.
What you need to do is pick a type that you want the list to be and specify it explicitly:
main = print $ maximum' ([] :: [()])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With