Accumulating errors with EitherT

前端 未结 2 1228
不知归路
不知归路 2021-01-03 00:33

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

2条回答
  •  無奈伤痛
    2021-01-03 00:46

    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.

提交回复
热议问题