Using CatchIO on StateT

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Using CatchIO on StateT

Dmitry V'yal
Greetings,

I found The MonadCatchIO-mtl package while looking for a way to catch
exceptions in my custom StateT s (ReaderT r IO) monad. CatchIO worked
flawlessly when handlers used the environment r from Reader, but things
broken when I tried to use state. According to source, the handler is
run with the same state which was passed to runStateT.

instance MonadCatchIO m => MonadCatchIO (StateT s m) where
     m `catch` f = StateT $ \s -> (runStateT m s)
                                    `Control.Monad.CatchIO.catch` (\e ->
runStateT (f e) s)

And my finalizing action depends on the current state. Can you give an
advice how to get the behavior I need?

Best regards,
Dmitry Vyal


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Using CatchIO on StateT

Gregory Collins-3
On Fri, Oct 12, 2012 at 12:49 PM, Dmitry Vyal <[hidden email]> wrote:
Greetings,

I found The MonadCatchIO-mtl package while looking for a way to catch exceptions in my custom StateT s (ReaderT r IO) monad. CatchIO worked flawlessly when handlers used the environment r from Reader, but things broken when I tried to use state. According to source, the handler is run with the same state which was passed to runStateT.

instance MonadCatchIO m => MonadCatchIO (StateT s m) where
    m `catch` f = StateT $ \s -> (runStateT m s)
                                   `Control.Monad.CatchIO.catch` (\e -> runStateT (f e) s)

And my finalizing action depends on the current state. Can you give an advice how to get the behavior I need?

Catching an exception in IO is a non-local transfer of control from one part of the program to another, and the only thing that is propagated is the exception value itself. In general, given that the exceptional value could be introduced to your thread from outside the execution context (i.e. using "killThread"), it's not possible to save the updated state value. If you wanted those semantics, you would need to use a side-effecting reference like IORef.

G
--
Gregory Collins <[hidden email]>

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe