我来自斯卡拉。所以我经常这样做:
println((1 to 10).filter(_ < 3).map(x => x*x))
在Haskell中,在我发现我可以使用$
和.
删除所有嵌套的括号后,我最近发现自己在写:
putStrLn . show . map (**2) . filter (< 3) $ [1..10]
现在,这有效,但代码从右向左读取,除非我转向阿拉伯语,否则我很难理解。
还有其他技巧让我从左到右连接功能吗?或者这只是Haskell惯用的方式?
答案 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}}运算符。