在之前的 question 中,我试图询问如何通过将它们组合在一起来混合纯函数和 monadic 函数,但是因为我的问题可能措辞错误而且我的例子过于简单,我认为讨论的方向是错误的,所以我认为我会再尝试。
这是一个混合了纯过滤器和一元过滤器的示例函数。在这个例子中,有一些纯过滤器在 monadic 过滤器之间排序,以尝试减少工作量。
findFiles target =
getDirectoryContents target >>=
return . filter (not . (=~ "[0-9]{8}\\.txt$")) >>=
return . filter (=~ "\\.txt$") >>=
filterM doesFileExist >>=
mapM canonicalizePath
在使用
return
混合纯函数的情况下,以这种方式编写它的好处是有一个从上到下的可视化数据流。不需要临时变量, fmap
, <$>
等。理想情况下,我可以去掉
return
以使其更干净。我有使用一些运算符的想法:(|>=) :: Monad m => a -> (a -> m b) -> m b
a |>= b = (return a) >>= b
但是我不知道如何编写这个函数来避免运算符优先级问题。这已经存在了吗?它类似于
<$>
但“另一个方向”。如果没有,我如何让这个运营商工作?更一般地说,是否有一种以这种管道方式编写代码的好方法,或者我需要像我之前的问题中描述的那样满足
fmap
和临时变量?
最佳答案
啊。就这么简单:
infixl 1 |>=
(|>=) = flip fmap
findFiles target =
getDirectoryContents target |>=
filter (not . (=~ "[0-9]{8}\\.txt$")) |>=
filter (=~ "\\.txt$") >>=
filterM doesFileExist >>=
mapM canonicalizePath
关于haskell - 如何以管道方式混合 Haskell monadic 和纯过滤器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20204002/