Haskell中的参数数量和无点数

时间:2012-07-14 20:29:57

标签: haskell arguments currying pointfree

使用多个模式匹配,即使使用无点,也不可能有不同数量的参数!

foo True b = b + 2
foo _ = id

不起作用。但

foo True = (+2)
foo _ = id

一样。有时我们只能在函数的一部分中使用无点,所以......

为什么呢? GHC太难了吗? :'(

2 个答案:

答案 0 :(得分:20)

  

为什么呢? GHC太难了吗?

即可。 GHC并不是太难。实际上,这是Haskell报告的错误。

请参阅:Haskell Report 2010 > Declarations and Bindings > Function bindings

  

函数绑定将变量绑定到函数值。变量x的函数绑定的一般形式是:

     

x p1 1 ... p1 k match1
  ...
  x pn 1 ... pn k matchn

     

[...等等......]

     

翻译:函数的一般绑定形式在语义上与等式等式(即简单模式绑定):

     

x = \ x 1 ... x k - >

的情况(x 1 ,...,x k )      

(p11,...,p1k)match1
  ...
  (pn1,...,pnk)matchn
  其中x i 是新标识符。

(强调我的)

虽然函数定义在语义上等效于到lambda&例如,Mihai建议,它们不一定按照这种方式编译。

问题是,Haskell报告定义函数声明,使得必须在等式的左侧具有相同数量的输入。事实上,k在第1和第n个函数声明行中保持相同(并且暗示,中间的所有行)都清楚地表明了这一点。 是限制的原因; 与GHC的实施细节无关

TL;博士

  

不允许它的选择只是风格问题。 - 奥古斯特

答案 1 :(得分:4)

每个函数方程必须具有相同数量的参数。这就是你的第一个例子失败的原因。

要解决此问题,请使用

foo True b = b + 2
foo _ x = id x

如您所见,两个方程都有相同数量的参数。

涉及模式匹配的多个方程式被转换为案例表达式。在您的情况下,foo大致翻译为

foo a b = case a of
    True -> b + 2
    _ -> id x

case的两个(所有)分支必须具有相同的类型,因此您将第一个示例转换为

foo a b = case a of
    True -> b + 2
    _ -> id

是错误的,因为分支有不同的类型。

当然,这是挥手,幕后发生的实际事情更加复杂