Haskell 美元运算符($)是否被视为坏形式?为什么?

Haskell 美元运算符($)是否被视为坏形式?为什么?,haskell,coding-style,Haskell,Coding Style,在Haskell中,我经常用$写表达式。我觉得它很自然,可读性也很好,但有时我读到它的形式不好,不明白为什么它应该是这样。以下都是好的形式: 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 . q

在Haskell中,我经常用$写表达式。我觉得它很自然,可读性也很好,但有时我读到它的形式不好,不明白为什么它应该是这样。

以下都是好的形式:

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
baz
qux
子表达式都很长时。以下是糟糕的形式:

foo x = bar $ baz $ quux $ x
有两个原因不太可取。首先,在重构过程中,可以将较少的子表达式复制并粘贴到辅助定义中;对于所有
($)
运算符,只有包含
x
参数的子表达式才是有效的重构,而对于
()
($)
运算符,甚至包括
条这样的子表达式。baz
baz。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

这意味着一些明显不同的东西。所以,通过避免使用此表单来证明您的代码是正确的。

您是否有关于它被描述为坏表单的参考资料?我偶尔也会看到类似于
bar的内容。baz$quux
条(baz.quux$x)
或其他混合物,通常在涉及其他中缀运算符时,或在概念上强调特定功能应用时。IMO,固定性参数没有组合样式让您通过简单的剪切粘贴将管道重构为函数这一事实那么引人注目。根据其当前的固定性,如果您有
bar$baz$qux$x
,这相当于
bar。巴兹。quux$x
。当然,后者比前者更受鼓励。我真的看不出
$
的优先性或固定性在改变,
$
的重点是优先级较低,不能低于0,所以
f$g$hx
很好。就我个人而言,我不喜欢
f。G当
$
表单只使用一个运算符时,h$x
使用了两个运算符(因此有两个概念-组合和应用)。@Stephentelley是否更清楚地说
($)
的关联性可能会改变?正如你所说,优先级是正确的。