15

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

foo True b = b + 2
foo _ = id

例如不起作用。但

foo True = (+2)
foo _ = id

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

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

4

2 回答 2

20

为什么?GHC太难了吗?

没有。GHC 一点也不难。实际上,这是 Haskell 报告的错误。

请参阅:Haskell 报告 2010 > 声明和绑定 > 函数绑定

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

x p1 1 … p1 k match1
…<br> x pn 1 … pn k matchn

[……呜呜呜……]

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

x = \ x 1 … x k -> case (x 1 , …, x k )

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

(强调我的)

虽然函数定义在语义上等同于 lambda & case 表达式,但它们不一定像 Mihai 所建议的那样编译。

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

tl;博士

选择不允许它只是风格问题。– 八月

于 2012-07-15T02:03:01.940 回答
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

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

当然,这是挥手,幕后发生的实际事情要复杂得多

于 2012-07-14T20:35:38.027 回答