You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If we were to plumb a MonadCatch, MonadThrow, and MonadMask implementation through every carrier, we can use the finally from exceptions’s Control.Monad.Catch, which performs correctly:
I already made these comments on slack, but I’ll make them here as well. My primary piece of advice is: you should reread my MonadBaseControl blog post! 😉 It has a section on how to make finally (and things like it) not discard state.
However, don’t despair: there actually is a way to produce a lifted version of finally that preserves all state changes. It can’t be done by lifting finally directly, but if we reimplement finally in terms of simpler lifted functions that are more amenable to lifting, we can produce a lifted version of finally that preserves all the state:
finally'::MonadBaseControlIOm=>ma->mb->ma
finally' ma mb = mask' $\restore ->do
a <- liftBaseWith $\runInBase ->
try (runInBase (restore ma))
case a ofLeft e -> mb *> liftBase (throwIO (e ::SomeException))
Right s -> restoreM s <* mb
You should be able to do the same thing in fused-effects. Also, I would recommend taking a look at the discussion in polysemy-research/polysemy#84, which discusses related problems in the context of bracket.
See also this thread where @gelisam discusses the problem. Based on this, I think we’re going to want to change the type of
finally
(at a minimum).cf #180
The text was updated successfully, but these errors were encountered: