jarmond
jarmond

Reputation: 1382

Collect result from two monadic actions

I'm trying to tidy up the following into a nice one-liner:

(r1,r2) <- do
  r1 <- action1
  r2 <- action2
  return (r1,r2)

This snippet is itself inside a do-block. By looking at the type of (,) :: a -> b -> (a, b), I thought to use liftM2 (,) :: Monad m => m a -> m b -> m (a, b). Now I can write it as

(r1,r2) <- liftM2 (,) action1 action2

which is less repetitive, but doesn't look very intuitive. What I'm wondering, and can't seem to find, is whether there is a standard combinator to join these actions and tuple-up their results?

Upvotes: 2

Views: 102

Answers (1)

ZhekaKozlov
ZhekaKozlov

Reputation: 39536

Actually, liftM2 is intuitive but it needs some time to get used to. So, the answer is yes, liftM2 or liftA2 are the standard combinators for your case. If you really want a readable solution, there are a number of other options:

  • <*> operator: (,) <$> action1 <*> action2
  • MonadComprehensions extension: [(r1, r2) | r1 <- action1, r2 <- action2]

Upvotes: 4

Related Questions