Haskell 奇怪的类型推断缩小
Haskell strange type inference narrowing
GHCi 7.8.3
filter (\(a,b) -> a>0) :: (Ord a, Num a) => [(a, t)] -> [(a, t)]
符合预期^
fstGt0 xs = filter (\(a,b) -> a>0) xs
也是同类型,但是
fstGt0 = filter (\(a,b) -> a>0)
推断为
fstGt0 :: [(Integer, t)] -> [(Integer, t)]
为什么?
此外,如果我用
在解释器中定义 fstGt0
let fstGt0 = filter (\(a,b) -> a>0)
它有预期的类型。
这看起来像是 单态限制 的效果(引入是因为语言中存在不连贯的东西,语言设计者无法想出更丑陋的东西):如果某物看起来像一个值而不是一个函数(带参数),它就不能是多态的。 (您的 fstGt0
没有参数。)
有一组有序的默认类型,它们试图被替换以自动满足单态限制。 (这就是你得到 Integer
的原因。)
至于问题的 GHCi 部分,我不确定。我不确定 GHCi 的 let
与编译后的 let
有多少相似之处,以及 let
-expressions.
中代码的单态性限制是否存在一些例外情况
必须有一个标志来关闭限制。
GHCi 7.8.3
filter (\(a,b) -> a>0) :: (Ord a, Num a) => [(a, t)] -> [(a, t)]
符合预期^
fstGt0 xs = filter (\(a,b) -> a>0) xs
也是同类型,但是
fstGt0 = filter (\(a,b) -> a>0)
推断为
fstGt0 :: [(Integer, t)] -> [(Integer, t)]
为什么? 此外,如果我用
在解释器中定义 fstGt0let fstGt0 = filter (\(a,b) -> a>0)
它有预期的类型。
这看起来像是 单态限制 的效果(引入是因为语言中存在不连贯的东西,语言设计者无法想出更丑陋的东西):如果某物看起来像一个值而不是一个函数(带参数),它就不能是多态的。 (您的 fstGt0
没有参数。)
有一组有序的默认类型,它们试图被替换以自动满足单态限制。 (这就是你得到 Integer
的原因。)
至于问题的 GHCi 部分,我不确定。我不确定 GHCi 的 let
与编译后的 let
有多少相似之处,以及 let
-expressions.
必须有一个标志来关闭限制。