在Haskell中从左到右链接方法(而不是从右到左)

时间:2015-11-08 11:37:56

标签: scala haskell function-composition

我来自斯卡拉。所以我经常这样做:

println((1 to 10).filter(_ < 3).map(x => x*x))

在Haskell中,在我发现我可以使用$.删除所有嵌套的括号后,我最近发现自己在写:

putStrLn . show . map (**2) . filter (< 3) $ [1..10] 

现在,这有效,但代码从右向左读取,除非我转向阿拉伯语,否则我很难理解。

还有其他技巧让我从左到右连接功能吗?或者这只是Haskell惯用的方式?

3 个答案:

答案 0 :(得分:16)

不幸的是,这是Haskell惯用的方式。但&运算符可能会执行您想要的操作。

import Data.Function ((&))

[1..10] & filter (< 3) & map (**2) & show & putStrLn

基本上,(&) = flip ($)。同样,Control.Arrow.(>>>) = flip (.)

更新(6个月以后):我不得不承认,这个问题对我来说是一个很大的挫败感,我一直在玩这个潜在的解决方案:

https://gist.github.com/obadz/9f322df8ba6c8a9767683d2f86af8589#file-directionalops-hs-L81

答案 1 :(得分:5)

是的,这是惯用的Haskell。不是阿拉伯语,而是数学,源于作文的语法。另请参阅Haskell composition (.) vs F#'s pipe forward operator (|>)

尽管如此,即使在Haskell中你有时也喜欢在另一个方向上编写你的电话,你会发现一些库(例如基础4.8.0以来的Data.Function)已经定义了

(&) = flip ($)

这样您就可以将来电表达为

[1..10] & filter (< 3) & map (**2) & show & putStrLn

答案 2 :(得分:2)

为什么不建立新的运营商?

(#) :: a -> (a -> b) -> b
(#) = flip id

现在你可以写

[1..10] # filter (< 3) # map (**2) # show # putStrLn

这相当于(&)的{​​{1}}运算符。