monad-primitive-0.1: Control/Monad/Primitive/Class.hs
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
-- |
-- Module : Control.Monad.Primitive.Class
-- Copyright : (c) 2013 Aleksey Khudyakov
-- License : BSD3
--
-- Maintainer : alexey.skladnoy@gmail.com
-- Stability : experimental
-- Portability : non-portable
module Control.Monad.Primitive.Class (
MonadPrim(..)
) where
import Control.Monad.ST (ST)
import Control.Monad.Primitive (PrimMonad)
import Control.Monad.Trans.Class (lift)
import Data.Monoid (Monoid)
import Control.Monad.Trans.Cont (ContT)
import Control.Monad.Trans.Error (ErrorT,Error)
import Control.Monad.Trans.Identity (IdentityT)
import Control.Monad.Trans.Maybe (MaybeT)
import Control.Monad.Trans.Reader (ReaderT)
import Control.Monad.Trans.RWS.Strict as S (RWST)
import Control.Monad.Trans.RWS.Lazy as L (RWST)
import Control.Monad.Trans.State.Strict as S (StateT)
import Control.Monad.Trans.State.Lazy as L (StateT)
import Control.Monad.Trans.Writer.Strict as S (WriterT)
import Control.Monad.Trans.Writer.Lazy as L (WriterT)
-- | Monads in which computation based on primitive monad (instance of
-- 'PrimMonad') could be embedded. Instances must obey following laws:
--
-- > liftPrim . return = return
-- > liftPrim (m >>= f) = liftPrim m >>= liftPrim f
class (PrimMonad (BasePrimMonad m), Monad m) => MonadPrim m where
type BasePrimMonad m :: * -> *
liftPrim :: BasePrimMonad m a -> m a
instance MonadPrim IO where
type BasePrimMonad IO = IO
liftPrim = id
instance MonadPrim (ST s) where
type BasePrimMonad (ST s) = (ST s)
liftPrim = id
instance MonadPrim m => MonadPrim (ContT r m) where
type BasePrimMonad (ContT r m) = BasePrimMonad m
liftPrim = lift . liftPrim
instance (MonadPrim m, Error e) => MonadPrim (ErrorT e m) where
type BasePrimMonad (ErrorT e m) = BasePrimMonad m
liftPrim = lift . liftPrim
instance MonadPrim m => MonadPrim (IdentityT m) where
type BasePrimMonad (IdentityT m) = BasePrimMonad m
liftPrim = lift . liftPrim
instance MonadPrim m => MonadPrim (MaybeT m) where
type BasePrimMonad (MaybeT m) = BasePrimMonad m
liftPrim = lift . liftPrim
instance MonadPrim m => MonadPrim (ReaderT r m) where
type BasePrimMonad (ReaderT r m) = BasePrimMonad m
liftPrim = lift . liftPrim
instance (MonadPrim m, Monoid w) => MonadPrim (S.RWST r w s m) where
type BasePrimMonad (S.RWST r w s m) = BasePrimMonad m
liftPrim = lift . liftPrim
instance (MonadPrim m, Monoid w) => MonadPrim (L.RWST r w s m) where
type BasePrimMonad (L.RWST r w s m) = BasePrimMonad m
liftPrim = lift . liftPrim
instance MonadPrim m => MonadPrim (S.StateT s m) where
type BasePrimMonad (S.StateT s m) = BasePrimMonad m
liftPrim = lift . liftPrim
instance MonadPrim m => MonadPrim (L.StateT s m) where
type BasePrimMonad (L.StateT s m) = BasePrimMonad m
liftPrim = lift . liftPrim
instance (MonadPrim m, Monoid w) => MonadPrim (S.WriterT w m) where
type BasePrimMonad (S.WriterT w m) = BasePrimMonad m
liftPrim = lift . liftPrim
instance (MonadPrim m, Monoid w) => MonadPrim (L.WriterT w m) where
type BasePrimMonad (L.WriterT w m) = BasePrimMonad m
liftPrim = lift . liftPrim