[Haskell-cafe] Monad-control rant
Mikhail Vorozhtsov
mikhail.vorozhtsov at gmail.com
Mon Nov 14 07:25:34 CET 2011
On 11/14/2011 06:55 AM, Bas van Dijk wrote:
> Hi Mikhail,
>
> your type class:
>
> class MonadAbort e μ ⇒ MonadRecover e μ | μ → e where
> recover ∷ μ α → (e → μ α) → μ α
>
> looks a lot like the MonadCatchIO type class from MonadCatchIO-transformers:
>
> class MonadIO m => MonadCatchIO m where
> catch :: E.Exception e => m a -> (e -> m a) -> m a
>
> I haven't looked at your code in detail but are you sure your
> continuation based AIO monad doesn't suffer from the same unexpected
> behavior as the ContT monad transformer with regard to catching and
> handling exceptions?
Yes, I'm sure. The reason why it works is because finally/bracket/etc
are not implemented on top of 'recover' (i.e. they don't assume that
throwing an exception is the only reason control can escape). The
following class takes care of it:
class (Applicative μ, Monad μ) ⇒ MonadFinally μ where
finally' ∷ μ α → (Maybe α → μ β) → μ (α, β)
finally ∷ μ α → μ β → μ α
finally m = fmap fst . finally' m . const
Finalizers have type 'Maybe α → μ β' so we can
(a) Thread transformer side effects properly:
instance MonadFinally μ ⇒ MonadFinally (L.StateT s μ) where
finally' m f = L.StateT $ \s → do
~(~(mr, _), ~(fr, s'')) ← finally' (L.runStateT m s) $ \mbr → do
let ~(a, s') = case mbr of
Just ~(x, t) → (Just x, t)
Nothing → (Nothing, s)
L.runStateT (f a) s'
return ((mr, fr), s'')
(b) Detect that control escaped computation before producing a result
(finalizer will be called with 'Nothing' in that case).
instance (MonadFinally μ, Error e) ⇒ MonadFinally (ErrorT e μ) where
finally' m f = ErrorT $ do
~(mr, fr) ← finally' (runErrorT m) $ \mbr →
runErrorT $ f $ case mbr of
Just (Right a) → Just a
_ → Nothing
return $ (,) <$> mr <*> fr
That of course does not mean that I can use 'finally' and friends with
ContT, but I can use them with monads which are carefully /implemented/
on top of ContT but do not expose it's full power to the users.
More information about the Haskell-Cafe
mailing list