haskell - 如何以管道方式混合 Haskell monadic 和纯过滤器?

标签 haskell pipe operator-keyword

在之前的 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/

相关文章:

haskell - "Persistently"Haskell 中的不纯 (IO) 向量,具有类似数据库的持久接口(interface)

c - C 中的多个管道

c - 在c中的管道中使用popen

pipe - 结合 Enum.map 和 Enum.each

oracle - Airflow Oracle 运算符(operator)

r - 模型.矩阵错误 : $ operator is invalid for atomic vectors

c++ - 当作为参数传递的对象超出范围时,析构函数是否会调用自身?

haskell : "instance (Enum a, Bounded a) => Random a"和 "=> Arbitrary a"

performance - Haskell 的 `seq` 冗余地评估参数?

haskell - 在 Haskell 中选择配对函数