Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 564
burgerkalif Avatar asked Sep 16 '25 17:09

burgerkalif


1 Answers

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' ([] :: [()])
like image 176
decorator-factory Avatar answered Sep 19 '25 06:09

decorator-factory