【问题标题】:Why is the $! operator right-associative?为什么是美元!运算符右结合?
【发布时间】:2014-05-09 17:18:24
【问题描述】:

我刚刚学习 Haskell,我仍然不完全清楚何时以及如何强制执行严格的评估

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

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

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

f $! x $! y $! z

让它做我想做的事?

我完全误解了$!运营商?

【问题讨论】:

  • 为什么不直接写一个函数 !$$! 的反向固定来做你想要的?
  • 问题是为什么这个函数还没有这样定义。我想知道我这样写的愿望是否反映了对 Haskell 工作原理的误解。
  • 如果你只是在学习 Haskell,我认为你不应该搞乱严格的应用程序。很少需要。

标签: haskell lazy-evaluation associativity


【解决方案1】:

这是为了反映$ 的固定性。您可以为 $$! 的固定性错误提供一个很好的案例。

【讨论】:

  • Prelude 运算符位于Haskell report
  • @dspyz 请注意,没有 Haskell 运算符列表之类的东西。 *%^*%^*&&$&%^ 是 Haskell 运算符吗?好吧,如果某个库定义了它,它可能是。
  • @dspyz 要按名称搜索 Haskell 运算符和函数,请尝试 Hoogle(使用有限的包集,但也可以按类型搜索,这非常有用)或 Hayoo(仅搜索名称,但在所有 Hackage 中。)
  • @dspyz FP Complete 的 Hoogle 搜索比常规 Hoogle 更多的包,所以它可以很方便fpcomplete.com/hoogle
【解决方案2】:

反对

我在 haskell-prime 中找到了 2008 年的一项提议,使 $$! 运算符左关联:

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

【讨论】:

  • Older (2006),Haskell Cafe 中的类似讨论(他说:“$ 的关联性完全是错误的”):mail-archive.com/haskell-cafe@haskell.org/msg12549.html
  • 要使用普通$ 的引用策略以传统样式f $! g $! x 翻译表达式,需要某种严格的组合:f .! g $! x。我想知道:库中是否已经定义了这样的运算符?
  • 顺便说一句,当前的<$> 与当前常规的$ 一致:f <$> g <$> x 似乎等同于f . g <$> x。但是<$> 的另一个左关联版本没有多大意义,因为使用多个 Applicative 参数被写为 f <$> x <*> yg <*> x <*> y(对于纯 f 或 Applicative g)。 <*> 似乎已经是左关联的(正如 Haskell-prime 中的 $ 所需要的那样),并且优先级低于 <$>
  • 看来<$> 是左关联in the latest base(因此,与常规的$ 不一致),与我在上面的评论中所说的相反。但是我的<$> 来自我系统上的一个较旧的基地,是正确的关联! (show <$> show <$> Just 3 给我Just "\"3\"";或I don't understand what is happening, so I asked a question
  • 是的,存在(.!)Strict composition
猜你喜欢
  • 2011-11-16
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
  • 2014-12-10
  • 1970-01-01
  • 2016-08-30
  • 2019-02-06
  • 1970-01-01
相关资源
最近更新 更多