GHCi中函数的类型推断与从文件加载的不同

GHCi中函数的类型推断与从文件加载的不同

本文介绍了GHCi中函数的类型推断与从文件加载的不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 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中函数的类型推断与从文件加载的不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 11:40