寻找解释为什么以下定义不满足类型推断:
-- | nub' - naive Data.List.nub implementation with extra constraint
nub' :: (Eq a, Show a) => [a] -> [a]
nub' = foldr (\e ac -> if e `elem` ac then ac else e:ac) []
main = do
print $ nub' []
-- Error: No instance for (Show a0) arising from a use of ‘print’
-- The type variable ‘a0’ is ambiguous
-- Note: there are several potential instances:
Run Code Online (Sandbox Code Playgroud)
而添加Integral约束则有所不同
nub' :: (Eq a, Show a, Integral a) => [a] -> [a]
nub' = foldr (\e ac -> if e `elem` ac then ac else e:ac) []
main = do
print $ nub' []
-- outputs `[]'
Run Code Online (Sandbox Code Playgroud)
添加Integral约束的原因使得代码再次编译是默认机制启动,因为Integral它是子类Num,并且反过来使类型变量a 默认为Integer.
您可以阅读Haskell报告第4.3.4节中的细节,但是外带消息是它Num(或它的子类)约束为编译器提供了足够的信息来做出明智的猜测a应该是什么.
如果没有默认机制(您可以通过输入default ()我刚刚发现的方式来尝试这一点!),输入42GHCi会给出完全相同的错误信息,如果您想使用GHCi作为花哨的计算器,这不是很有用...