为了账号安全,请及时绑定邮箱和手机立即绑定

通过具有不同数量参数的方程式定义函数

通过具有不同数量参数的方程式定义函数

我今天注意到这样的定义safeDivide x 0 = xsafeDivide = (/)不可能。我很好奇这背后的(好的)原因是什么。必须有一个非常好的(毕竟是Haskell :)。注意:我不是在寻找上面代码的替代实现的建议,这是一个简单的例子来说明我的观点。
查看完整描述

3 回答

?
jeck猫

TA贡献1909条经验 获得超7个赞

我认为这主要是为了保持一致性,以便可以以相同的方式读取所有子句;可以这么说。也就是说,每个RHS在功能类型中都位于相同的位置。如果您允许的话,我认为也会掩盖很多愚蠢的错误。


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


safeDivide x 0 = x

safeDivide x y = (/) x y

现在考虑第二行是否改为safeDivide = undefined;在没有上一个子句的情况下,safeDivide它将是⊥,但是由于此处执行了eta扩展,所以它是\x y -> if y == 0 then x else ⊥-因此safeDivide = undefined实际上并没有定义safeDivide为⊥!国际海事组织,这似乎足以使人们有理由禁止此类条款。


查看完整回答
反对 回复 2019-11-02
?
GCT1015

TA贡献1827条经验 获得超4个赞

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


fn pat1a pat1b = r1

fn pat2a pat2b = r2

变成


fn = \a b -> case (a,b) of

  (pat1a, pat1b) -> r1

  (pat2a, pat2b) -> r2

这样一来,函数定义/ case语句的处理方式就很好并且保持一致,并且没有多余地且混乱地指定每个函数的含义。


仅当每个子句具有相同数量的参数时,这种翻译才真正有意义。当然,可能会有其他规则来解决此问题,但是它们会使翻译复杂化,但收效甚微,因为您可能不想为了读者的利益而定义这样的内容。


查看完整回答
反对 回复 2019-11-02
?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

Haskell之所以这样做,是因为它的前辈(如LML和Miranda)做到了。没有技术原因必须如此。具有较少参数的方程式可以进行eta展开。但是对于不同的方程式使用不同数量的参数可能是一种错字而不是有意的,因此在这种情况下,我们禁止在某些情况下明智且罕见的做法,以便在常见情况下获得更好的错误报告。


查看完整回答
反对 回复 2019-11-02
  • 3 回答
  • 0 关注
  • 532 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信