haskell - 混合 fmap 和绑定(bind) (>>=)

标签 haskell functional-programming coding-style

在 Haskell 中,当我必须混合调用 fmap 时/<$>>>=/=<< , 我总是以很多括号结尾。

例如,我在这里调用 listDirectoryAbs dir :: IO [String]然后链接一系列 filterfilterM , 以 fmap 结尾.

findDlls :: String -> IO [String]
findDlls dir = f <$> (filterM predicate1 =<< (filter predicate2 <$> (filterM predicate3 =<< listDirectoryAbs dir)))

因为所有这些嵌套表达式看起来很乱(至少对我而言),我最终重写了 f <$> xreturn . f =<< x .如果我随后翻转绑定(bind),我会得到更具可读性的内容:

findDlls dir = listDirectoryAbs dir
 >>= filterM predicate3
 >>= return . filter predicate2
 >>= filterM predicate1
 >>= return . f

正在重写f <$> x -> return . f =<< x -> x >>= return . f以任何方式“坏”?在这种情况下,是否有更好的方法来避免嵌套表达式?

可以使用do符号代替,但我想避免必须明确说明数据流并为每个返回值命名。

最佳答案

我不认为它是“坏的”(除非它放弃了那个特定 monad 的 fmap 中的优化),但是我不喜欢它的冗长。

我宁愿为此定义自己的运算符, <$$> has been suggested<&>会匹配 $ / & -对偶性良好(另见 Anyone ever flip (<$>) ):

infixl 1 <&>
(<&>) = flip (<$>)

findDlls dir = listDirectoryAbs dir
 >>= filterM predicate3
 <&> filter predicate2
 >>= filterM predicate1
 <&> f

顺便说一句,如果你的 monad 是 Arrow (例如函数),然后是 <<</>>>=<< 完美结合/>>= .

关于haskell - 混合 fmap 和绑定(bind) (>>=),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41552250/

相关文章:

haskell - 如何约束关联类型同义词?

haskell - 如何在Haskell中使用测试包中的assertRaises?

java - 实现常量对象的最佳方法是什么?

javascript - 从 Node JS 中的数组获取条目

java - 一致遍历两个列表的最佳样式

Java 风格的多重返回,用作 "Guards"

haskell - 通用 Trie Haskell 实现

反转或翻转顺序的 Haskell 新类型

functional-programming - Elm:为 Elm 程序生成信号图

haskell - FP 中模式匹配相对于条件的优势是什么(通俗地说)?