{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE UnicodeSyntax #-} module Control.Monad.Trans.Open ( OpenT , OpenT' -- ** Operations , close ) where import Control.Monad.Open.Class import Control.Applicative import Control.Monad import Control.Monad.Catch import Control.Monad.Cont.Class import Control.Monad.Error.Class import Control.Monad.RWS.Class import Control.Monad.Reader import Control.Monad.State import Control.Monad.Writer import Data.Monoid -- | A concrete structure implementing the 'MonadOpen' signature. -- newtype OpenT a b m b' = OpenT { _openT ∷ ReaderT (a → m b) m b' } deriving (Applicative, Functor, Monad, Alternative, MonadPlus, MonadIO, MonadCont, MonadFix, MonadThrow, MonadCatch, MonadMask, MonadError e, MonadWriter w, MonadState s) deriving instance MonadRWS r w s m ⇒ MonadRWS r w s (OpenT a b m) instance MonadTrans (OpenT a b) where lift = OpenT . lift instance MonadReader r m ⇒ MonadReader r (OpenT a b m) where ask = OpenT $ lift ask local f (OpenT x) = OpenT . ReaderT $ local f . (runReaderT x) -- | A simplified version of the 'OpenT' type which fixes the output parameter. type OpenT' a m b = OpenT a b m b instance Monad m ⇒ MonadOpen a b (OpenT a b m) where call x = do rec ← OpenT ask OpenT . lift $ rec x -- | An open operation may be closed. -- close ∷ Monad m ⇒ Op a (OpenT a b m) b → a → m b close o@(Op f) x = runReaderT (_openT $ f x) $ close o