haskellalternative-functormonadplus

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?


Solution

  • 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.