我对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
是在
应用程序
属于
加
,这有什么关系
当定义明显具有多态性时?
-
为什么
ghc
突然想到
分类
需要a
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
能够使用多态类型
Ord a => [a] -> [a]
对于
分类
?
-
为什么
ghc
对待
加
和
plus'
不同地
加
应该有
多态类型
Num a => a -> a -> a
我真的看不出这有什么不同
从类型
分类
然而,只有
分类
引发错误。
最后一件事:如果我评论一下
分类
文件编译。然而
如果我试着把它装进去
ghci
并检查我得到的类型:
*TestMono> :t plus
plus :: Integer -> Integer -> Integer
*TestMono> :t plus'
plus' :: Num a => a -> a -> a
为什么这种类型不适合
加
多态?
这是Haskell中关于单态性限制的典型问题
如[元问题]中所述(https://meta.stackoverflow.com/questions/294053/can-we-provide-a-canonical-questionanswer-for-haskells-monomorphism-restrictio).