An ambiguous type variable, but not in ghci?

Can someone explain why haskell uses an explicit type signature in the following example and how to modify it to avoid the need for an 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 ambiguity problem and makes zero-length printing:

 Îģ> :m +Data.List Îģ> print $ length $ nub [] 0 -- ?? can you explain ?? 

Update: It seems that even the same restriction as the length function of Data.List.nub does not stop complaining about the 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 
+5
source share
1 answer

The problem is that [] has a polymorphic type (Eq a) => [a] . Since length does not add any specific restriction.

In particular, the type length :

 length :: [a] -> Int 

which is even more permissive than nub :

 nub :: Eq a => [a] -> [a] 

The compiler must use a specific instance of length and cannot infer a type for a .

You now have two options:

  • Enable the ExtendedDefaultRules extension with {-# LANGUAGE ExtendedDefaultRules #-} at the beginning of the file.
  • To be explicit: ... L.nub ([] :: [Int])

I would recommend the second one by default, if you do not fully understand the consequences of the consequences of the first .

+9
source

Source: https://habr.com/ru/post/1205094/


All Articles