最佳答案
我对 Haskell 编译器有时如何推断出较少的类型感到困惑 比我期望的多态性,例如在使用无点定义时。
这似乎是一个“单态限制”的问题 编译器的旧版本。
考虑下面的 Haskell 程序:
{-# LANGUAGE MonomorphismRestriction #-}
import Data.List(sortBy)
plus = (+)
plus' x = (+ x)
sort = sortBy compare
main = do
print $ plus' 1.0 2.0
print $ plus 1.0 2.0
print $ sort [3, 1, 2]
如果我用 ghc
编译它,我不会得到任何错误,并且可执行文件的输出是:
3.0
3.0
[1,2,3]
如果我将 main
主体改为:
main = do
print $ plus' 1.0 2.0
print $ plus (1 :: Int) 2
print $ sort [3, 1, 2]
没有编译时错误,输出结果如下:
3.0
3
[1,2,3]
不过,如果我试着把它改成:
main = do
print $ plus' 1.0 2.0
print $ plus (1 :: Int) 2
print $ plus 1.0 2.0
print $ sort [3, 1, 2]
我得到一个输入错误:
test.hs:13:16:
No instance for (Fractional Int) arising from the literal ‘1.0’
In the first argument of ‘plus’, namely ‘1.0’
In the second argument of ‘($)’, namely ‘plus 1.0 2.0’
In a stmt of a 'do' block: print $ plus 1.0 2.0
同样的情况也发生在用不同类型两次调用 sort
时:
main = do
print $ plus' 1.0 2.0
print $ plus 1.0 2.0
print $ sort [3, 1, 2]
print $ sort "cba"
产生以下错误:
test.hs:14:17:
No instance for (Num Char) arising from the literal ‘3’
In the expression: 3
In the first argument of ‘sort’, namely ‘[3, 1, 2]’
In the second argument of ‘($)’, namely ‘sort [3, 1, 2]’
ghc
突然认为 plus
不是多态的并且需要 Int
参数?
对 Int
的唯一参考是在 plus
的 申请表中,这有什么关系
当定义明显是多态的时候?ghc
突然认为 sort
需要 Num Char
实例?此外,如果我尝试将函数定义放入它们自己的模块中,比如:
{-# LANGUAGE MonomorphismRestriction #-}
module TestMono where
import Data.List(sortBy)
plus = (+)
plus' x = (+ x)
sort = sortBy compare
我在编译时得到以下错误:
TestMono.hs:10:15:
No instance for (Ord a0) arising from a use of ‘compare’
The type variable ‘a0’ is ambiguous
Relevant bindings include
sort :: [a0] -> [a0] (bound at TestMono.hs:10:1)
Note: there are several potential instances:
instance Integral a => Ord (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
instance Ord () -- Defined in ‘GHC.Classes’
instance (Ord a, Ord b) => Ord (a, b) -- Defined in ‘GHC.Classes’
...plus 23 others
In the first argument of ‘sortBy’, namely ‘compare’
In the expression: sortBy compare
In an equation for ‘sort’: sort = sortBy compare
ghc
不能对 sort
使用多态类型 Ord a => [a] -> [a]
?ghc
治疗 plus
和 plus'
不同? plus
应该有
多态类型 Num a => a -> a -> a
,我看不出有什么不同
从类型的 sort
,但只有 sort
提出了一个错误。最后一件事: 如果我注释了 sort
的定义,文件就会被编译
如果我尝试加载到 ghci
并检查我得到的类型:
*TestMono> :t plus
plus :: Integer -> Integer -> Integer
*TestMono> :t plus'
plus' :: Num a => a -> a -> a
为什么 plus
的类型不是多态的?