在Haskell中卷曲

时间:2015-02-23 19:23:10

标签: haskell currying

我在Haskell中手动编写currying函数如下。 curry f = \x y -> f(x,y) 然后我使用这个max(x, y) = if x > y then x else y作为f,我写了max1 = curry max来获得curried函数

但这是不允许的。为什么这是错的?

1 个答案:

答案 0 :(得分:5)

你遇到了dreaded monomorphism restriction,它限制了Haskell推断多态类型的位置。

没有"外观"像一个函数 - 没有命名参数 - 不能有多态类型。问题是您的max函数 具有多态类型(适用于o类中的任何类型Ord),这会强制类型系统为max1选择一个概念可订购类型。由于没有要选择的默认类型,它会告诉您类型变量不明确。

有三种方法可以避免这种限制。正如您已经看到的那样,其中一个是使参数显式化,使整个绑定看起来像一个函数:

max1 x y = curry max x y

另一种是添加显式类型签名:

max1 :: Ord o => o -> o -> o
max1 = curry max

最后,您还可以通过在模块顶部添加编译器指令来关闭限制:

{-# LANGUAGE NoMonomorphismRestriction #-}

在所有这些中,最惯用的选择是添加类型签名。 通常,每个顶级名称都应该有一个显式的类型签名。这不是强制性的,但被认为是好的样式,因为除了避免单态问题,它还有助于捕获更多错误并使错误消息更容易阅读。如果您打开GHC中的所有警告(带有-Wall标志),它将警告您没有类型签名的顶级名称。