我只是在学习 Haskell,但我仍然不完全清楚何时以及如何强制执行严格的评估
当我想要一个函数严格评估其参数时,我发现自己在写
((f $! x) $! y ) $! z
这看起来很奇怪。不应该$!是左联想的,所以我可以写
f $! x $! y $! z
让它做我想做的事吗?
我完全误解了$!操作员?
我只是在学习 Haskell,但我仍然不完全清楚何时以及如何强制执行严格的评估
当我想要一个函数严格评估其参数时,我发现自己在写
((f $! x) $! y ) $! z
这看起来很奇怪。不应该$!是左联想的,所以我可以写
f $! x $! y $! z
让它做我想做的事吗?
我完全误解了$!操作员?
这是为了反映$
. 您可以为两者都提供一个很好的案例$
并且$!
具有错误的固定性。
我在 haskell-prime 中找到了 2008 年的一项提案,以使$
and$!
运算符具有左关联性:
https://ghc.haskell.org/trac/haskell-prime/wiki/ChangeDollarAssociativity
反对该提议只有一个论点:“这会破坏很多代码”。
相反,有四个参数支持 left-associative($)
,最后一个与您的相同,并且被认为是最重要的。简而言之,它们是:
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