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

Opa*_*Opa 4 haskell pipe operator-keyword

在之前的一个问题中,我试着询问如何通过将它们组合在一起来混合纯函数和monadic函数,但是因为我可能说错了我的问题并且我的例子太简单了,我认为讨论方向错误,所以我认为我会再尝试.

这是一个混合纯和一元过滤器的示例函数.在这个例子中,有一些纯粹的过滤器在monadic过滤器之间排序,试图减少工作量.

findFiles target = 
  getDirectoryContents target                    >>=
  return . filter (not . (=~ "[0-9]{8}\\.txt$")) >>=
  return . filter (=~ "\\.txt$")                 >>=
  filterM doesFileExist                          >>=
  mapM canonicalizePath
Run Code Online (Sandbox Code Playgroud)

以这种方式编写它的好处是纯函数混合使用return,就是从上到下存在可视化的数据.无需临时变量,fmap,<$>等.

理想情况下,我可以摆脱return它,使其更清洁.我有想法使用一些运算符:

(|>=) :: Monad m => a -> (a -> m b) -> m b
a |>= b = (return a) >>= b
Run Code Online (Sandbox Code Playgroud)

但我不知道如何编写此函数以避免运算符优先级问题.这已经存在了吗?它类似于<$>"其他方向".如果没有,我该如何使这个操作符工作?

更一般地说,是否有一种以这种管道方式编写代码的好方法,或者我需要解决fmaps和临时变量,如我之前的问题所述?

Opa*_*Opa 7

啊.就这么简单:

infixl 1 |>=
(|>=) = flip fmap

findFiles target = 
  getDirectoryContents target           |>=
  filter (not . (=~ "[0-9]{8}\\.txt$")) |>=
  filter (=~ "\\.txt$")                 >>=
  filterM doesFileExist                 >>=
  mapM canonicalizePath
Run Code Online (Sandbox Code Playgroud)