我没想到以下代码可以运行:
foo :: (Num a) => a -> a
foo x = x + x
main = do
print (foo (read "7"))
因为无法根据代码完全推断出(读取“7”)的类型。但GHC(6.12.3)认为不然并打印14。
如果“7”更改为“7.2”,则代码将失败并显示“no parse”。这里发生了什么? Haskell如何决定使用哪个Read实例?
答案 0 :(得分:12)
这是由Haskell的defaulting rules for the Num
class引起的。如果你添加了
default (Double, Integer)
到文件的顶部,然后你会得到以下结果:
main = do
print (foo (read "7")) -- prints "14.0"
print (foo (read "7.2")) -- prints "14.2"
简而言之,默认规则是尝试“尝试做正确的事情”并在程序中存在模糊类型时避免编译错误。不幸的是,在这种情况下,它会针对运行时错误交换编译时错误。
你可以像这样禁用默认:
default ()
会强制您通过类型注释明确消除此类术语的类型歧义:
print (foo (read "7" :: Int))
答案 1 :(得分:2)
Int是此实例中的默认类型。见第二节。 6.3,歧义和类型违约,在Haskell的历史中:与班级一起懒惰,