问题描述
我在 test.hs
中编写了一个函数 add'
:
add'= \xy - > x + y
然后我加载 test.hs
在GHCi(版本7.8.3)中,并键入:t add'
来观察 add'
是什么类型。结果看起来不正确:
* Main> :t add'
add':: Integer - >整数 - >整数
但是如果我输入:t(\xy - > x + y)
直接在GHCi中,结果是正确的:
* Main> :t(\ x y - > x + y)
(\ xy - > x + y):: Num a => a - > a - > a
然后我尝试重写 add'
在 test.hs
后面跟:type
它们在GHCi中:
add1 = \xy - > x + y
add2 = \ x - > \y - > x + y
add3 xy = x + y
结果如下:
add1 :: Integer - >整数 - >整数
add2 ::整数 - >整数 - >整数
add3 :: Num a => a - > a - > a
但是使用 let
子句来定义一个函数,然后:type
它们或:type
直接在GHCi 所有结果中输入lambda类型 Num a => a - > a - > a
他们为什么不同?这是GHC的一个bug吗?
可怕的单态限制。单态限制使您的函数的类型签名专用于单一类型。您可以使用扩展名 NoMonomorphismRestriction
关闭该功能: { - # LANGUAGE NoMonomorphismRestriction# - }
add1 = \xy - > x + y
add2 = \ x - > \y - > x + y
add3 xy = x + y
然后当你加载类型ghci他们将是:
λ> :t add1
add1 :: Num a => a - > a - > a
λ> :t add2
add2 :: Num a => a - > a - > a
λ> :t add3
add3 :: Num a => a - > a - > a
I wrote a function add'
in test.hs
:
add' = \x y -> x + y
Then I loaded test.hs
in GHCi (version 7.8.3), and typed :t add'
to watch what type add'
is. The result looks like incorrect:
*Main> :t add'
add' :: Integer -> Integer -> Integer
But if I typed :t (\x y -> x + y)
straightly in GHCi, the result is correct:
*Main> :t (\x y -> x + y)
(\x y -> x + y) :: Num a => a -> a -> a
Then I tried to rewrite the add'
in test.hs
as followed and :type
them in GHCi:
add1 = \x y -> x + y
add2 = \x -> \y -> x + y
add3 x y = x + y
The results are:
add1 :: Integer -> Integer -> Integer
add2 :: Integer -> Integer -> Integer
add3 :: Num a => a -> a -> a
But use let
clause to define a function and then :type
them or :type
the lambdas straightly in GHCi all results in type of Num a => a -> a -> a
Why are they different? Is it a bug of GHC?
You have hit upon the dreaded monomorphism restriction. Monomorphism restriction makes the type signature of your function specialized to a single type. You can turn off that using the extension NoMonomorphismRestriction
:
{-# LANGUAGE NoMonomorphismRestriction #-}
add1 = \x y -> x + y
add2 = \x -> \y -> x + y
add3 x y = x + y
And then when you load the types in ghci they will be:
λ> :t add1
add1 :: Num a => a -> a -> a
λ> :t add2
add2 :: Num a => a -> a -> a
λ> :t add3
add3 :: Num a => a -> a -> a
这篇关于GHCi中函数的类型推断与从文件加载的不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!