3 回答
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为⊥!国际海事组织,这似乎足以使人们有理由禁止此类条款。
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语句的处理方式就很好并且保持一致,并且没有多余地且混乱地指定每个函数的含义。
仅当每个子句具有相同数量的参数时,这种翻译才真正有意义。当然,可能会有其他规则来解决此问题,但是它们会使翻译复杂化,但收效甚微,因为您可能不想为了读者的利益而定义这样的内容。
TA贡献2036条经验 获得超8个赞
Haskell之所以这样做,是因为它的前辈(如LML和Miranda)做到了。没有技术原因必须如此。具有较少参数的方程式可以进行eta展开。但是对于不同的方程式使用不同数量的参数可能是一种错字而不是有意的,因此在这种情况下,我们禁止在某些情况下明智且罕见的做法,以便在常见情况下获得更好的错误报告。
添加回答
举报