From db70c4f88293c8a7902e132826dba2a7ecfe0a74 Mon Sep 17 00:00:00 2001 From: "Yang, Bo" Date: Sat, 18 Jan 2020 01:48:03 -0800 Subject: [PATCH 1/2] Implement MonadError for `ContT e (Codensity m)` --- src/Control/Monad/Codensity.hs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Control/Monad/Codensity.hs b/src/Control/Monad/Codensity.hs index 3ccc3ea..364299f 100644 --- a/src/Control/Monad/Codensity.hs +++ b/src/Control/Monad/Codensity.hs @@ -42,10 +42,12 @@ import Control.Applicative import Control.Monad (MonadPlus(..)) import qualified Control.Monad.Fail as Fail import Control.Monad.Free +import Control.Monad.Error.Class import Control.Monad.IO.Class import Control.Monad.Reader.Class import Control.Monad.State.Class import Control.Monad.Trans.Class +import Control.Monad.Trans.Cont import Data.Functor.Adjunction import Data.Functor.Apply import Data.Functor.Kan.Ran @@ -248,6 +250,12 @@ instance (Functor f, MonadFree f m) => MonadFree f (Codensity m) where wrap t = Codensity (\h -> wrap (fmap (\p -> runCodensity p h) t)) {-# INLINE wrap #-} +instance MonadError e (ContT e (Codensity m)) where + throwError e = ContT (const (pure e)) + catchError c recover = ContT $ \successHandler -> Codensity $ \errorHandler -> + runCodensity (runContT c successHandler) + $ \e -> runCodensity (runContT (recover e) successHandler) errorHandler + instance MonadReader r m => MonadState r (Codensity m) where get = Codensity (ask >>=) {-# INLINE get #-} From b576025bffa9ab408ecdbe2bbd69c372ae8b3c2e Mon Sep 17 00:00:00 2001 From: "Yang, Bo" Date: Sat, 18 Jan 2020 02:36:37 -0800 Subject: [PATCH 2/2] Add a forwarder instance of MonadError --- src/Control/Monad/Codensity.hs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Control/Monad/Codensity.hs b/src/Control/Monad/Codensity.hs index 364299f..de6c5fd 100644 --- a/src/Control/Monad/Codensity.hs +++ b/src/Control/Monad/Codensity.hs @@ -250,12 +250,17 @@ instance (Functor f, MonadFree f m) => MonadFree f (Codensity m) where wrap t = Codensity (\h -> wrap (fmap (\p -> runCodensity p h) t)) {-# INLINE wrap #-} -instance MonadError e (ContT e (Codensity m)) where +instance {-# OVERLAPPING #-} MonadError e (ContT e (Codensity m)) where throwError e = ContT (const (pure e)) catchError c recover = ContT $ \successHandler -> Codensity $ \errorHandler -> runCodensity (runContT c successHandler) $ \e -> runCodensity (runContT (recover e) successHandler) errorHandler +instance MonadError e m => MonadError e (Codensity m) where + throwError e = Codensity (const (throwError e)) + catchError c recover = + Codensity $ \k -> catchError (runCodensity c k) $ \e -> runCodensity (recover e) k + instance MonadReader r m => MonadState r (Codensity m) where get = Codensity (ask >>=) {-# INLINE get #-}