不明确的类型变量,但不是在ghci?

时间:2014-10-20 13:49:52

标签: haskell

有人可以解释为什么haskell在以下示例中强制执行显式类型签名以及如何修改它以避免需要显式声明?

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])

令人惊讶的是,在ghci中以交互方式编写的相同代码没有歧义问题,并且打印零长度:

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

更新 似乎同样限制Data.List.nub长度函数不会停止对模糊类型的抱怨:

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

1 个答案:

答案 0 :(得分:10)

问题是[]具有多态类型(Eq a) => [a]。由于length未添加任何特定约束。

具体而言length的类型是:

length :: [a] -> Int

nub更宽松:

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

编译器需要在那里使用length的特定实例,并且无法推断出a的类型。

现在您有两个选择:

  1. 使用文件开头的ExtendedDefaultRules打开{-# LANGUAGE ExtendedDefaultRules #-}扩展名。
  2. 明确:... L.nub ([] :: [Int])
  3. 我建议默认使用第二个,除非您完全理解consequences of the first one