packages feed

transformers-base-0.3: src/Control/Monad/Base/Control.hs

{-# LANGUAGE UnicodeSyntax #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}

module Control.Monad.Base.Control (
    MonadBaseControl(..),
    controlBase,
    liftBaseOp,
    liftBaseOp_
  ) where

import Data.Monoid
import Control.Monad
import Control.Monad.Base
import Control.Monad.Trans.Identity
import Control.Monad.Trans.Maybe
import Control.Monad.Trans.Error
import Control.Monad.Trans.List
import Control.Monad.Trans.Reader
import qualified Control.Monad.Trans.Writer.Lazy as L
import qualified Control.Monad.Trans.Writer.Strict as S
import qualified Control.Monad.Trans.State.Lazy as L
import qualified Control.Monad.Trans.State.Strict as S
import qualified Control.Monad.Trans.RWS.Lazy as L
import qualified Control.Monad.Trans.RWS.Strict as S
import Control.Monad.Trans.Control

class MonadBase η μ ⇒ MonadBaseControl η μ | μ → η where
  -- | Helper for lifting control operations from the base monad.
  liftBaseControl ∷ (RunInBase μ η → η α) → μ α

instance MonadBaseControl IO IO where
  liftBaseControl = idLiftControl

instance MonadBaseControl η μ ⇒ MonadBaseControl η (IdentityT μ) where
  liftBaseControl = liftLiftControlBase liftBaseControl

instance MonadBaseControl η μ ⇒ MonadBaseControl η (MaybeT μ) where
  liftBaseControl = liftLiftControlBase liftBaseControl

instance (Error e, MonadBaseControl η μ)
       ⇒ MonadBaseControl η (ErrorT e μ) where
  liftBaseControl = liftLiftControlBase liftBaseControl

instance MonadBaseControl η μ ⇒ MonadBaseControl η (ListT μ) where
  liftBaseControl = liftLiftControlBase liftBaseControl

instance MonadBaseControl η μ ⇒ MonadBaseControl η (ReaderT r μ) where
  liftBaseControl = liftLiftControlBase liftBaseControl

instance (Monoid w, MonadBaseControl η μ)
       ⇒ MonadBaseControl η (L.WriterT w μ) where
  liftBaseControl = liftLiftControlBase liftBaseControl

instance (Monoid w, MonadBaseControl η μ)
       ⇒ MonadBaseControl η (S.WriterT w μ) where
  liftBaseControl = liftLiftControlBase liftBaseControl

instance MonadBaseControl η μ ⇒ MonadBaseControl η (L.StateT s μ) where
  liftBaseControl = liftLiftControlBase liftBaseControl

instance MonadBaseControl η μ ⇒ MonadBaseControl η (S.StateT s μ) where
  liftBaseControl = liftLiftControlBase liftBaseControl

instance (Monoid w, MonadBaseControl η μ)
       ⇒ MonadBaseControl η (L.RWST r w s μ) where
  liftBaseControl = liftLiftControlBase liftBaseControl

instance (Monoid w, MonadBaseControl η μ)
       ⇒ MonadBaseControl η (S.RWST r w s μ) where
  liftBaseControl = liftLiftControlBase liftBaseControl

controlBase ∷ MonadBaseControl η μ ⇒ (RunInBase μ η → η (μ α)) → μ α
controlBase = join . liftBaseControl

liftBaseOp ∷ MonadBaseControl η μ
           ⇒ ((α → η (μ β)) → η (μ γ))
           →  (α →    μ β ) →    μ γ
liftBaseOp base m = controlBase $ \runInBase → base $ runInBase . m

liftBaseOp_ ∷ MonadBaseControl η μ
           ⇒ (η (μ β) → η (μ γ))
           →     μ β  →    μ γ
liftBaseOp_ base m = controlBase $ \runInBase → base $ runInBase m