Home > other >  Why does supplying an empty list to this Haskell function give compiler error?
Why does supplying an empty list to this Haskell function give compiler error?

Time:06-05

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.

CodePudding user response:

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. 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' ([] :: [()])
  • Related