任何人都可以解释为什么 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 ??
Update:它似乎甚至受到同样的限制Data.List.nub
length 函数不会停止对不明确类型的抱怨:
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
问题是[]
具有多态类型(Eq a) => [a]
. Since length
不添加任何特定的约束。
具体类型为length
is:
length :: [a] -> Int
这甚至比nub
:
nub :: Eq a => [a] -> [a]
编译器需要使用特定的实例length
在那里并且无法推断出类型a
.
现在你有两个选择:
- 打开
ExtendedDefaultRules
扩展与{-# LANGUAGE ExtendedDefaultRules #-}
在文件的开头。
- 明确:
... L.nub ([] :: [Int])
我默认推荐第二个,除非你完全理解第一个的后果.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)