用不同数量的参数定义一个函数

我今天注意到这样一个定义

safeDivide x 0 = x safeDivide = (/) 

不可能。 我只是好奇这背后的(好)理由是什么。 必须有一个非常好的(毕竟是Haskell :))。

注意:我不想看上面的代码的替代实现的build议,这是一个简单的例子来certificate我的观点。

我认为这主要是为了保持一致,所以所有的条款都可以用同样的方式阅读。 即每个RHS在functiontypes中处于相同的位置。 如果你也允许的话,我认为会掩盖一些愚蠢的错误。

也有一个轻微的语义怪癖:说编译器填充这些子句与其他子句具有相同数量的模式; 即你的例子将成为

 safeDivide x 0 = x safeDivide xy = (/) xy 

现在考虑第二行是否已经safeDivide = undefined ; 在没有前面的子句的情况下, safeDivide将是 ,但是由于在这里执行的eta扩展,它是\xy -> if y == 0 then x else ⊥ safeDivide = undefined – 所以safeDivide = undefined实际上并没有定义safeDivide ! 这似乎令人困惑,足以certificate禁止这样的条款,国际海事组织。

具有多个子句的函数的含义由Haskell标准(第4.4.3.1节)通过转换为lambda和case语句来定义:

 fn pat1a pat1b = r1 fn pat2a pat2b = r2 

 fn = \ab -> case (a,b) of (pat1a, pat1b) -> r1 (pat2a, pat2b) -> r2 

这样做的function定义/事件陈述的方式是好的,一致的,每一个的含义都没有冗余和混淆。

当每个子句具有相同数量的参数时,这种翻译才有意义。 当然,可以有额外的规则来解决这个问题,但是它们会使翻译复杂化,因为你可能不想为了读者的缘故定义类似的东西。

Haskell是这样做的,因为它是前辈(如LML和Miranda)所做的。 没有技术上的原因必须是这样的; 具有较less参数的方程可以被扩展。 但是对于不同的方程式有不同的参数可能是一个错字,而不是故意的,所以在这种情况下,我们禁止了一些合理的和罕见的东西来获得更好的错误报告。