Haskell函数从左到右执行

21

我经常使用一个函数,它让我能够以一种更自然的方式编写代码。

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上搜索没有结果
是否有任何标准库包含类似的功能?如果我的代码中有这样一个常见部分是特定于个人的,那么可能会使其他人难以阅读我的代码。

5
根据OOHaskell,我更偏向于将这个操作称为 #,因为它从根本上来说与对象的方法选择相同,并且在OCaml中用于此操作的运算符是 #。或者,仿照F#,我们可以使用 |> - Philip JF
1
有一个提议要将 flip ($) 引入 Data.Function,但由于无法达成共识,因此被放弃了。对于初学者来说,这样的东西是否有用(相对于会让人困惑等)存在争议。以下是讨论链接:http://markmail.org/message/vsplpb7aajp7goqo?q=python - David
你能接受Yoann B.的答案吗?&运算符现在已经被广泛使用(大概是多亏了高度有影响力的lens库,该库将其包含在其标准编码风格中)。 - leftaroundabout
3个回答

23

虽然没有内置此功能,但Control.Category.(>>>)接近此功能:它是 flip (.),所以您可以编写

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

作为

f = sort >>> group >>> aggregate

对于您的($:)组合器,有众多定义和名称。我认为函数通常比简单的应用更适合流水线风格,所以我并不感到非常需要它;但(>>>)有点丑陋。

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


2
无论丑陋与否,我认为 (>>>) 是直观的,因为它看起来像 (>>=),这是一个类似的从左到右的管道。 - amindfv
真遗憾它是 flip (.) 而不是 flip ($). 但我猜 >>> 是你能得到的最接近的了。 - Xodarap
还有一个来自 http://hackage.haskell.org/packages/archive/diagrams-lib/0.4.0.1/doc/html/Diagrams-Util.html 的 (#) ,但它的中缀优先级与 ($) 相差很远。 - mgsloan

5
您所描述的反向应用运算符现在已经成为标准包base(自4.8.0起)的一部分,作为&运算符
请注意,此运算符的优先级低于您提出的运算符(infixl 1)。

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接