在Haskell中卷曲

xwa*_*ang 1 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函数

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

Tik*_*vis 5

你遇到了可怕的单态限制,它限制了Haskell可以推断多态类型的位置.

不像函数那样"看起来"的绑定没有命名参数 - 不能具有多态类型.问题是,你的max功能确实有一个多态型(它可以用于任何类型o是在Ord类),强制类型系统接单沈志南订购类型max1.由于没有要选择的默认类型,它会告诉您类型变量不明确.

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

max1 x y = curry max x y
Run Code Online (Sandbox Code Playgroud)

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

max1 :: Ord o => o -> o -> o
max1 = curry max
Run Code Online (Sandbox Code Playgroud)

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

{-# LANGUAGE NoMonomorphismRestriction #-}
Run Code Online (Sandbox Code Playgroud)

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