-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
throw envelope errors in a short-circuiting monad #3
Comments
@lexi-lambda Left some notes on playing around with this at #7 (comment) |
Just to get it on the table: You could just use This may seem hacky, but in some cases I prefer this over pulling out |
I ended up making an data EnvelopeT es m a = EnvelopeT
{ runEnvelopeT :: m (Envelope es a)
} deriving Functor
instance Monad m => Applicative (EnvelopeT es m) where
pure :: a -> EnvelopeT es m a
pure a = EnvelopeT $ pureSuccEnvelope a
(<*>) :: EnvelopeT es m (a -> b) -> EnvelopeT es m a -> EnvelopeT es m b
(<*>) = ap
instance Monad m => Monad (EnvelopeT es m) where
(>>=) :: EnvelopeT es m a -> (a -> EnvelopeT es m b) -> EnvelopeT es m b
(EnvelopeT m) >>= k = EnvelopeT $ do
env <- m
case env of
SuccEnvelope a -> runEnvelopeT $ k a
ErrEnvelope err -> pure $ ErrEnvelope err
instance MonadTrans (EnvelopeT es) where
lift :: Monad m => m a -> EnvelopeT es m a
lift m = EnvelopeT $ do
val <- m
pureSuccEnvelope val
instance MonadIO m => MonadIO (EnvelopeT es m) where
liftIO :: IO a -> EnvelopeT es m a
liftIO = lift . liftIO
pureSuccEnvT :: Applicative m => a -> EnvelopeT es m a
pureSuccEnvT = EnvelopeT . pureSuccEnvelope
pureErrEnvT :: (Applicative m, IsMember e es) => e -> EnvelopeT es m a
pureErrEnvT = EnvelopeT . pureErrEnvelope Then you can write helper functions for your application like this: runDbOr404EnvT ::
( HasPool r
, IsMember DbNotFoundErr es
, MonadBaseControl IO m
, MonadReader r m
)
=> ReaderT SqlBackend m (Maybe a)
-> EnvelopeT es m a
runDbOr404EnvT query = do
pool' <- lift $ view pool
maybeRes <- lift $ runSqlPool query pool'
case maybeRes of
Just a -> pureSuccEnvT a
Nothing -> pureErrEnvT DbNotFoundErr I haven't yet checked the laws for |
Would be nice if there was a blessed implementation of this. |
@23Skidoo I'm working on putting this together for you. |
@23Skidoo I just sent a PR adding an I also made a release to hackage with http://hackage.haskell.org/package/servant-checked-exceptions-2.2.0.0 This doesn't add an mtl-like |
Awesome, thanks! |
It would be nice to be able to throw
Envelope
errors in some sort of short circuiting monad.I'm not sure if there is a good / clean / easy way to implement this, but I would be interested in different possibilities.
The text was updated successfully, but these errors were encountered: