Reputation: 5073
g ll =
foldlM (\ some_list b -> do
part <- f b
return (some_list ++ part)) [] ll
In above piece of code I use do statement
just because the f
function return a monad type: M a
where a
is a list.
( I "unpack" that list with <-
. This is why I need do statement
). Can I avoid it and write that more concisely? ( Yes, I know that I can write it using >>=
but I also consider something nicer.)
Upvotes: 1
Views: 140
Reputation: 48611
foldlM
is the wrong tool for the job. You can use it, as chepner's answer shows, but the way you're concatenating lists could get expensive. Luka Rahne's one-liner is much better:
g ll = fmap concat (mapM f ll)
Another option is to use foldr
directly:
g = foldr (\x r -> (++) <$> f x <*> r) (pure [])
Another way to write the second version, by inlining the foldr
:
g [] = pure []
g (x : xs) = (++) <$> f x <*> g xs
Upvotes: 6
Reputation: 531878
Your do
expression
do
part <- f b
return (some_list ++ part)
follows the extract-apply-return pattern that fmap
captures (due to the identity fmap f k = k >>= return . f
part
from the computation f b
(some_list ++)
to part
This can be done in one step with fmap
:
-- foldlM (f b >>= return . (some_list ++)) [] ll
foldlM (\some_list b -> fmap (some_list ++) (f b)) [] ll
Upvotes: 1