美元符号($)被认为是一种不好的形式吗?为什么?

17
在Haskell中,我经常使用 $ 符号编写表达式。我发现它很自然和易读,但有时我会读到说这是坏习惯,而我不明白为什么应该这样说。

7
你有没有相关参考资料表明这种做法是不好的? - bobbymcr
1个回答

22
以下所有格式都是正确的:
foo = bar . baz . quux
foo x = bar . baz . quux $ x
foo x = (bar . baz . quux) x
foo x = bar (baz (quux x))

我按照自己的偏好粗略排序了它们,尽管口味因人而异,而且情境可能需要不同的选择。我还偶尔看到

foo = bar
    . baz
    . quux

barbazquux子表达式都很长时,以下写法是不好的:

foo x = bar $ baz $ quux $ x

这种写法不太好的原因有两个。第一个是在重构时无法复制和粘贴较少的子表达式到辅助定义中;对于所有的($)操作符,只有包含x参数的子表达式才是有效的重构,而对于(.)($)操作符,甚至像bar . bazbaz . quux这样的子表达式也可以被提取出来放到单独的定义中。

第二个选择(.)的原因是为了预防($)的优先级可能会发生变化;目前,($)的优先级为infixr,意味着它右结合,就像这样:

foo x = bar $ (baz $ (quux $ x))

然而,如果($)infixl的话,在更多的表达式中它将会非常有用;例如:

foo h = f (g x) (h y)
foo h = f $ g x $ h y
foo h = (f $ g x) $ h y

...现在无法不使用括号表示。 "不良格式"的例子,如果使用infixl应用程序解析,将会是:

foo x = ((bar $ baz) $ quux) $ x

这意味着有着显著不同的含义。因此,通过避免使用这种形式来保证您的代码具有未来的可扩展性。


6
我偶尔也看到过像 bar . baz $ quux xbar (baz . quux $ x) 这样的东西,通常在涉及其他中缀运算符或强调特定函数应用程序的情况下出现。 - C. A. McCann
6
在我看来,固定性的论点并不像组合风格那样令人信服,因为组合风格使你能够将管道重构为一个简单的剪切粘贴函数。 - ehird
在当前的修复版本中,如果你有 bar $ baz $ quux $ x,这等同于 bar . baz . quux $ x。当然,我们鼓励使用后者而不是前者。 - Dan Burton
2
我真的看不到$的优先级或固定性会改变 - $的重点是要具有低优先级,而且你无法比0更低,所以f $ g $ h x 是可以的。个人不喜欢用 f . g . h $ x,因为它使用了两个操作符(因此涉及两个概念——组合和应用),而 $ 表单则只使用了一个。 - stephen tetley
@stephentetley 你认为说($)的结合性可能会改变更清晰吗?正如你所说,优先级水平恰到好处。 - Daniel Wagner
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接