用不同数量的参数定义一个函数
我今天注意到这样一个定义
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参数的方程可以被扩展。 但是对于不同的方程式有不同的参数可能是一个错字,而不是故意的,所以在这种情况下,我们禁止了一些合理的和罕见的东西来获得更好的错误报告。