19

我有一个经常使用的函数,它允许我以一种对我来说更自然的方式编写代码。

infixl 6 $:
($:) :: a -> (a -> b) -> b
a $: f = f a

这让我可以做类似的事情

let x = getData
        $: sort
        $: group
        $: aggregate

代替

let x = aggregate 
        $ group 
        $ sort 
        $ getData

我最近了解到 Clojure 内置了类似的东西(我不太了解 Clojure,但我认为它会被编写(-> getData sort group aggregate)?)这让我想知道 Haskell 是否也内置了它。不过, Hoogle没有任何结果

是否有包含类似内容的标准库?如果我有这样一个共同的部分是特殊的,它可能会让其他人难以阅读我的代码。

4

3 回答 3

22

没有内置这样的东西,但Control.Category.(>>>)很接近:它是flip (.),所以你可以写

f x = x $: sort $: group $: aggregate

作为

f = sort >>> group >>> aggregate

您的组合器不乏定义和名称。($:)我认为函数往往比简单的应用程序更适合管道风格,所以我觉得对它没有太大的需求;(>>>)不过有点难看。

(此外,Haskell 的非严格语义意味着数据的流动不一定是箭头指向的方向;毕竟,它甚至可以在有机会查看参数aggregate之前提供第一个构造sort函数。所以我倾向于只需使用(.)and ($);我已经习惯了这个顺序。)

于 2012-04-04T01:32:41.697 回答
3

您所描述的反向应用程序运算符现在是标准包base(自 4.8.0 起)的一部分,作为&operator

请注意,此运算符的定义优先级低于您建议的 ( infixl 1)。

于 2016-04-15T14:07:00.687 回答
1

在 Hackage 中有一个名为 Flow ( https://hackage.haskell.org/package/flow-1.0.10/docs/Flow.html ) 的库,由 Taylor Fausak 为这个确切的需求而创建。

它使用|>运算符(受 F# 启发)充当最后一个线程。

例如:

3 |> succ |> recip |> negate
-0.25
于 2018-02-06T13:59:53.947 回答