在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
。如果我然后翻转绑定,我会得到更具可读性的东西:
findDlls dir = listDirectoryAbs dir
>>= filterM predicate3
>>= return . filter predicate2
>>= filterM predicate1
>>= return . f
重写f <$> x
- &gt; return . f =<< x
- &gt; x >>= return . f
以任何方式“糟糕”?在这种情况下,是否有一种避免嵌套表达式的优选方法?
我可以使用do
符号,但我想避免明确数据流并为每个返回值命名。
答案 0 :(得分:4)
我不认为这是“坏”(除非它在该特定单子的fmap
中丧失优化),但我不喜欢它的冗长。
我宁愿为此定义自己的运算符,<$$>
has been suggested或<&>
会匹配$
/ &
- 对偶性很好(另请参阅 {{ 3}} 的):
infixl 1 <&>
(<&>) = flip (<$>)
findDlls dir = listDirectoryAbs dir
>>= filterM predicate3
<&> filter predicate2
>>= filterM predicate1
<&> f
顺便说一句,如果您的monad是Anyone ever flip (<$>)(例如函数),则<<<
/ >>>
与=<<
/ >>=
很好地结合。