I’ve written the following function (using the these library):
import Control.Applicative (Alternative ((<|>)), optional)
import Data.These (These(..))
asumThese :: (Alternative f, Monad f) => f a -> f b -> f (These a b)
asumThese x y = optional x >>= case
Just x' -> maybe (This x') (These x') <$> optional y
Nothing -> That <$> y
Is there a way I can remove the Monad
constraint, or is there no way out of using bind?
My gut feeling says I can’t avoid the Monad
constraint here, but can anyone give me an intuition of why that is the case? Just so in the future I have a better sense of what sort of functions I likely need Monad
and which ones I can generalise to Applicative
and/or Alternative
?
I sense it has something to do with needing Monad
for sequencing, but I can’t quite put my finger on it, because f <$> x <*> y
parses things in a different sequence to f <$> y <*> x
, so there’s still sequencing in Applicative
.