Can anybody explain why haskell enforces explicit type signature in the following example and how to modify it to avoid need of the explicit declaration ?
import qualified Data.List as L
main = do
print $ length $ L.nub [1,1,2,3] -- 3, passed (Eq a, Num a) => [a]
print $ length $ L.nub [] -- ambiguous type error, passed (Eq a) => [a]
-- can help type system with explicit signature but how to avoid ?
print $ length $ L.nub ([] :: [Int])
Surprisingly the same code written interactively in ghci has no issue with ambiguity and does prints zero length:
λ> :m +Data.List
λ> print $ length $ nub []
0 -- ?? can you explain ??
Update:
It seems even same restricted as Data.List.nub
length function won't stop complaints about ambiguous type:
length' :: Eq a => [a] -> Int
length' [] = 0
length' (x:xs) = 1 + length' xs
main = do
print $ length' $ nub []
-- No instance for (Eq a0) arising from a use of ‘length'’
-- The type variable ‘a0’ is ambiguous
The problem is that []
has the polymorphic type (Eq a) => [a]
. Since length
doesn't add any particular constraint.
Specifically the type of length
is:
length :: [a] -> Int
which is even more permissive than nub
:
nub :: Eq a => [a] -> [a]
The compiler needs to use a specific instance of length
there and is not able to deduce a type for a
.
Now you have two options:
ExtendedDefaultRules
extension with {-# LANGUAGE ExtendedDefaultRules #-}
at the beginning of the file.... L.nub ([] :: [Int])
I'd recommend the 2nd one by default, unless you fully understand the consequences of the first one.
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