美元算子($)被认为是坏形式吗?为什么?

lui*_*dro 17 haskell coding-style

在Haskell中,我经常用$表示表达式.我发现它非常自然和可读,但我有时读到它是不好的形式,不明白为什么它应该是.

Dan*_*ner 22

以下都是好形式:

foo = bar . baz . quux
foo x = bar . baz . quux $ x
foo x = (bar . baz . quux) x
foo x = bar (baz (quux x))
Run Code Online (Sandbox Code Playgroud)

我把它们按照我的偏好粗略排列,尽管味道总是不同,上下文可能需要不同的选择.我偶尔也见过

foo = bar
    . baz
    . quux
Run Code Online (Sandbox Code Playgroud)

当每个的bar,bazquux子表达式很长.以下是不好的形式:

foo x = bar $ baz $ quux $ x
Run Code Online (Sandbox Code Playgroud)

有两个原因,这是不太可取的.首先,在重构期间,可以将更少的子表达式复制并粘贴到辅助定义中; 对于所有($)运算符,只有包含x参数的子表达式才是有效的重构,而使用(.)($)运算符甚至是子表达式,bar . baz或者baz . quux可以将其拉出到单独的定义中.

更喜欢的第二个理由(.)是预期可能会改变固定性($); 目前,($)infixr,意味着它与权利相关联,如下:

foo x = bar $ (baz $ (quux $ x))
Run Code Online (Sandbox Code Playgroud)

但是,($)如果有更多的表达方式会有用infixl; 例如,像

foo h = f (g x) (h y)
foo h = f $ g x $ h y
foo h = (f $ g x) $ h y
Run Code Online (Sandbox Code Playgroud)

......如果没有括号,目前无法表达.当用infixl应用程序解析时,"坏形式"示例将是

foo x = ((bar $ baz) $ quux) $ x
Run Code Online (Sandbox Code Playgroud)

这意味着显着不同的东西.因此,通过避免使用此表单来保护您的代码.

  • 我偶尔也会看到像酒吧这样的东西.baz $ quux x`或`bar(baz.quux $ x)`或其他混合物,通常在涉及其他中缀运算符时,或者在概念上强调特定功能应用程序时. (6认同)
  • IMO,固定性参数不如组合风格允许您通过简单的剪切和粘贴将管道重构为函数这一事实引人注目. (6认同)
  • 我真的看不出 `$` 的优先级或固定性发生变化 - `$` 的重点是优先级较低,并且不能低于 0,所以 `f $ g $ hx` 就可以了。我个人不喜欢`f。G 。h $ x` 因为它使用两个运算符(因此两个概念 - 组合和应用),而 `$` 形式仅使用一个运算符。 (2认同)