我在Haskell中手动编写currying函数如下.
curry f = \x y -> f(x,y)
然后我用它max(x, y) = if x > y then x else y作为f,我写了max1 = curry max以获得curried函数
但这是不允许的.为什么这是错的?
你遇到了可怕的单态限制,它限制了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标志),它将警告您没有类型签名的顶级名称.
| 归档时间: |
|
| 查看次数: |
310 次 |
| 最近记录: |