在 Haskell 中,当我必须混合调用 fmap
时/<$>
和 >>=
/=<<
, 我总是以很多括号结尾。
例如,我在这里调用 listDirectoryAbs dir :: IO [String]
然后链接一系列 filter
和 filterM
, 以 fmap
结尾.
findDlls :: String -> IO [String]
findDlls dir = f <$> (filterM predicate1 =<< (filter predicate2 <$> (filterM predicate3 =<< listDirectoryAbs dir)))
因为所有这些嵌套表达式看起来很乱(至少对我而言),我最终重写了 f <$> x
至 return . 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/