Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine and then branch in MonadPlus/Alternative

I recently wrote

do
  e <- (Left <$> m) <|> (Right <$> n)
  more actions
  case e of
    Left x -> ...
    Right y -> ...

This seems awkward. I know that protolude (and some other packages) define

-- Called eitherP in parser combinator libraries
eitherA :: Alternative f => f a -> f b -> f (Either a b)

But even with that, it all feels a bit manual. Is there some nice pattern I haven't seen for tightening it up?

like image 738
dfeuer Avatar asked Dec 29 '25 12:12

dfeuer


1 Answers

I just noticed that OP expressed this same idea in a comment. I'm going to post my thoughts anyway.


Coyoneda is a neat trick, but it's a little overkill for this particular problem. I think all you need is regular old continuations.

Let's name those ...s:

do
  e <- (Left <$> m) <|> (Right <$> n)
  more actions
  case e of
    Left x -> fx x
    Right y -> fy y

Then, we could instead have written this as:

do
  e <- (fx <$> m) <|> (fy <$> n)
  more actions
  e

This is slightly subtle — it's important to use <$> there even though it looks like you might want to use =<< so that the result of the first line is actually a monadic action to be performed later rather than something that gets performed right away.

like image 83
DDub Avatar answered Jan 01 '26 16:01

DDub