【问题标题】:Haskell function composition (.) and function application ($) idioms: correct useHaskell 函数组合 (.) 和函数应用 ($) 成语:正确使用
【发布时间】:2011-03-03 02:54:10
【问题描述】:

我一直在阅读Real World Haskell,我已经接近尾声了,但是我一直在纠结(.)($) 运算符的风格问题。 p>

当你编写一个由其他函数组成的函数时,你可以这样写:

f = g . h

但是当你在这些函数的末尾应用一些东西时,我会这样写:

k = a $ b $ c $ value

但是这本书会这样写:

k = a . b . c $ value

现在,在我看来,它们在功能上是相同的,在我看来它们的作用完全相同。然而,我看的越多,我就越看到人们以书中的方式编写函数:首先使用(.) 撰写,然后仅在最后使用($) 附加一个值来评估批次(没有人这样做它有许多美元成分)。

是否有理由使用比使用所有($) 符号更好的书籍方式?还是这里有一些我没有得到的最​​佳实践?还是它是多余的,我根本不应该担心?

【问题讨论】:

  • 注意第二个例子可以写成k = a $ b $ c value
  • 是的,它可以,正如下面 Zifre 提到的,但我决定把它留在那里,因为它不会伤害任何东西,并使他的(现在是你的)cmets 有意义。不过谢谢你。 +1 :)
  • 另一种常用的方法是a . b $ c value,我不像第三个例子那么喜欢,但节省了一些字符。

标签: haskell coding-style function-composition


【解决方案1】:

我想我可以从权威人士那里回答这个问题。

是否有理由使用比使用所有 ($) 符号更好的书籍方式?

没有什么特别的原因。 Bryan 和我都喜欢减少线路噪音。 .$ 更安静。因此,本书使用了f . g . h $ x 语法。

【讨论】:

  • 嗯,我不能指望比这个更好的答案了。来自其中一位作者本人。 :) 这是有道理的,当我阅读时,它在页面上看起来确实安静得多。将此标记为答案,因为它直接回答了问题。感谢您的答复;而且,事实上,这本书。
  • 不是不同意作者的观点,但我认为创造而不是使用的心智模型还有另一个更突出的原因。 Haskell 用户倾向于认为f.g.h 是一个新的聪明创造,而不是f(g(h()))。现在他们正在调用他们创建的一个新的(尽管是匿名的)函数,而不是像 PHP 用户那样仅仅链接一个包含预制函数调用的大字典。
  • 这是一个有趣的说法:“减少线路噪音”和“比安静”。我从来没有想过用这个术语来编程语言,但它非常有意义。
【解决方案2】:

它们确实是等价的:请记住,$ 运算符基本上什么都不做。 f $ x 计算结果为 f x$ 的目的是它的固定性行为:右关联和最小优先级。去掉$并使用括号代替中缀优先进行分组,代码sn-ps如下所示:

k = a (b (c (value)))

k = (a . b . c) value

更喜欢. 版本而不是$ 版本的原因与更喜欢上面带括号的版本的原因相同:美观。

虽然,有些人可能想知道使用中缀运算符而不是括号是否是基于某种潜意识的冲动,以避免与 Lisp 有任何可能的相似之处(开个玩笑……我想?)。

【讨论】:

    【解决方案3】:

    我要补充一点,在f . g $ x 中,f . g 是一个有意义的句法单元。

    同时,在f $ g $ x 中,f $ g 不是一个有意义的单位。 $ 的链可以说是更加必要的——首先得到xg的结果,然后对它执行f然后对它做foo然后等等。

    同时,. 链可以说更具声明性,并且在某种意义上更接近以数据流为中心的视图 - 组合一系列函数,并最终将它们应用于某事。

    【讨论】:

    • 我正在学习 Haskell(没有编写任何有意义的代码),但我喜欢将 $ 视为一种“管道”运算符。它很像终端 |管道(数据从右到左流动除外),但与终端进程一样,每个单元都是明确独立的。
    • $ 运算符的行为似乎类似于 F# 中的 <| 运算符。我相信两者的定义是一样的,事实上——在 F# 中,(<|) a b = a b 和在 Haskell 中,a $ b = a b,它们本质上是等价的。
    • @BalinKingOfMoria <| 运算符将值传递给函数,而不是将函数传递给值 - 您的代码示例将改为使用 |> 运算符。
    • @Quackmatic 哦。不知道有多个版本(我没有经常使用 F#)。
    【解决方案4】:

    对我来说,我认为答案是(a)整洁,如Don said; (b) 我发现当我编辑代码时,我的函数可能以无点样式结束,然后我所要做的就是删除最后一个 $ 而不是返回并更改所有内容。当然,这是一个小问题,但很好。

    【讨论】:

    • 是的,这样写是一个很好的理由,如果你想以函数组合结尾,那么它会更快。 :) 是的,可以节省击键,但更重要的是时间。 +1
    【解决方案5】:

    this haskell-cafe thread 上有一个关于这个问题的有趣讨论。显然有少数观点认为$ 的正确关联性是"just plain wrong",选择f . g . h $ x 而不是f $ g $ h $ x 是回避问题的一种方式。

    【讨论】:

    【解决方案6】:

    这只是风格问题。然而,这本书的方式对我来说更有意义。它组合所有函数,然后将其应用于值。

    你的方法看起来很奇怪,最后一个$是不必要的。

    但是,这真的没关系。在 Haskell 中,通常有很多很多正确的方法来做同样的事情。

    【讨论】:

    • 我没有注意到最后一个 $ 是不必要的,但我应该有。谢谢,我会把它留在那里,以便人们知道这条评论的含义。
    【解决方案7】:

    我意识到这是一个非常古老的问题,但我认为还有另一个尚未提及的原因。

    如果你声明一个新的无点函数f . g . h,你传入的值将被自动应用。不过写f $ g $ h就不行了。

    我认为作者喜欢组合方法的原因是因为它导致了构建函数的良好实践。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-29
      • 2016-04-30
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多