Add MonadThrow instance for Codensity#83
Conversation
|
Thanks for the PR! I think adding a instance MonadThrow m => MonadThrow (Codensity m) where
throwM = lift . throwM(I'm not sure if this implementation is meaningfully different from the one you've provided, but it wouldn't surprise me if there were a way to observe the difference between the two instances in certain corner cases.) I'm more reluctant to add a module Main where
import Control.Monad.Catch
import Control.Monad.Codensity
import Control.Monad.IO.Class
bracket_' :: MonadCatch m
=> m a -- ^ computation to run first (\"acquire resource\")
-> m b -- ^ computation to run last when successful (\"release resource\")
-> m b -- ^ computation to run last when an exception occurs
-> m c -- ^ computation to run in-between
-> m c -- returns the value from the in-between computation
bracket_' before after afterEx thing = do
_ <- before
r <- thing `onException` afterEx
_ <- after
return r
f :: Codensity IO String
f = do
bracket_' (say "acquired") (say "released-successful") (say "released-exception") (say "executed")
say "Hello!"
() <- error "error"
return "success"
where
say = liftIO . putStrLn
main :: IO ()
main = runCodensity f (return . Right @String @String) >>= printWhen run, this produces: Notice that the exception handler is run twice, once after a successful computation within |
|
I see, thank you for the explanation. I'm not seeing a way around this issue and I suspect it's a fundamental flaw with this approach. I could still edit this pull request to be only about Luckily, in my case it was easy enough to move things around to have the exception be caught in a section where I was operating within the underlying monad (kaol/servant-wasm-client@b411fd6 if you are curious). |
|
Up to you! I think a |
8b7158b to
edfa516
Compare
|
Okay, I force pushed a version with the |
The
exceptionspackage is a transitive dependency of this package viasemigroupoidsso these instances can't be there.