I have the following little mini-sample application of a web API that takes a huge JSON document and is supposed to parse it in pieces and report error messages for each of
We could actually code this as an arrow (Kleisli transformer).
newtype EitherAT x m a b = EitherAT { runEitherAT :: a -> m (Either x b) }
instance Monad m => Category EitherAT x m where
id = EitherAT $ return . Right
EitherAT a . EitherAT b
= EitherAT $ \x -> do
ax <- a x
case ax of Right y -> b y
Left e -> return $ Left e
instance (Monad m, Semigroup x) => Arrow EitherAT x m where
arr f = EitherAT $ return . Right . f
EitherAT a *** EitherAT b = EitherAT $ \(x,y) -> do
ax <- a x
by <- b y
return $ case (ax,by) of
(Right x',Right y') -> Right (x',y')
(Left e , Left f ) -> Left $ e <> f
(Left e , _ ) -> Left e
( _ , Left f ) -> Left f
first = (***id)
Only, that would violate the arrow laws (you can't rewrite a *** b to first a >>> second b without losing a's error information). But if you basically see all the Lefts as merely a debugging device, you might argue it's okay.