为什么是$!运算符右关联?

时间:2014-05-09 17:18:25

标签: haskell lazy-evaluation associativity

我刚刚学习Haskell而且我还不完全清楚何时以及如何严格评估

当我想要一个函数来严格评估它的参数时,我发现自己正在编写

((f $! x) $! y ) $! z

这看起来很奇怪。不应该$!是左联想所以我可以写

f $! x $! y $! z

让它做我想做的事吗?

我完全误解了$!操作

2 个答案:

答案 0 :(得分:11)

反映$的固定性。对于$$!具有错误的固定性,您可以提供一个非常好的案例。

答案 1 :(得分:5)

反对

的论点

我在2008年的haskell-prime中找到了一项提案,要求$$!运营商保持联想:

https://ghc.haskell.org/trac/haskell-prime/wiki/ChangeDollarAssociativity

反对该提案只有一个论点:"这会打破代码的批次"。

赞成的论点

相反,给出了四个支持左关联($) 的论据,最后一个与你的相同,并且被认为是最重要的。简而言之,它们是:

  • 0)给定表达式f x y,有两个应用程序,我们就可以编写f $ x $ y

  • 1)现在,通过右关联($),我们可以将f . g . h $ x写为f $ g $ h $ x

    但是:\x -> f $ g $ h $ x ==> f $ g $ h无效,

    这样可以更好地编写这样的管道,因为它可以更容易地清理代码

  • 2)左关联($)允许您除了用(。)消除的括号之外还消除更多括号,例如:

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

  • 3)你的论点:$!的正确关联版本不方便,因为它产生的结果如下:((f $! x) $! y) $! z而不是f $! x $! y $! z

结论

我支持使用更好的左关联版本的应用程序运算符,在我们的代码开头重新定义它们,如下所示:

import Prelude hiding (($), ($!))

infixl 0  $, $!
($), ($!) :: (a -> b) -> a -> b  
f $  x =         f x
f $! x = x `seq` f x