避免在foldM中使用do语句

Gil*_*esz 1 haskell

g ll = 
  foldlM (\ some_list b -> do
    part <- f b
    return (some_list ++ part)) [] ll
Run Code Online (Sandbox Code Playgroud)

在上面的代码中我使用的do statement只是因为f函数返回monad类型: M awhere a是一个列表.(我用"解包"该列表<-.这就是我需要的原因do statement).我可以避免它并更简洁地写出来吗?(是的,我知道我可以用它来写它,>>=但我也考虑更好的东西.)

dfe*_*uer 6

foldlM这是工作的错误工具.你可以使用它,正如chepner的答案所示,但你连接列表的方式可能会变得昂贵.Luka Rahne的单线程更好:

g ll = fmap concat (mapM f ll)
Run Code Online (Sandbox Code Playgroud)

另一种选择是foldr直接使用:

g = foldr (\x r -> (++) <$> f x <*> r) (pure [])
Run Code Online (Sandbox Code Playgroud)

编写第二个版本的另一种方法是通过内联foldr:

g [] = pure []
g (x : xs) = (++) <$> f x <*> g xs
Run Code Online (Sandbox Code Playgroud)