mtl-evil-instances-0.1: src/Control/Monad/Instances/Evil.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-|
This module exports several very overlapping instances for the type classes
defined in the @mtl@ library, and should be used with caution, or not at all
(see the package description). The instances are defined:
* @instance ('MonadTrans' t, 'Monad' (t m), 'MonadBase' b m) => 'MonadBase' b (t m)@
* @instance ('MonadTransControl' t, 'Monad' (t m), 'MonadCont' m) => 'MonadCont' (t m)@
* @instance ('MonadTransControl' t, 'Monad' (t m), 'MonadError' e m) => 'MonadError' e (t m)@
* @instance ('MonadTransControl' t, 'Monad' (t m), 'MonadFix' m) => 'MonadFix' (t m)@
* @instance ('MonadTrans' t, 'Monad' (t m), 'MonadIO' m) => 'MonadIO' (t m)@
* @instance ('MonadTrans' t, 'Monad' (t m), 'MonadReader' r m) => 'MonadReader' r (t m)@
* @instance ('MonadTrans' t, 'Monad' (t m), 'MonadRWS' r w s m) => 'MonadRWS' r w s (t m)@
* @instance ('MonadTrans' t, 'Monad' (t m), 'MonadState' s m) => 'MonadState' s (t m)@
* @instance ('MonadTrans' t, 'Monad' (t m), 'MonadWriter' w m) => 'MonadWriter' w (t m)@
* @instance ('MonadBaseControl' b m, 'MonadCont' b) => 'MonadCont' m@
* @instance ('MonadBaseControl' b m, 'MonadError' e b) => 'MonadError' e m@
* @instance ('MonadBaseControl' b m, 'MonadFix' b) => 'MonadFix' m@
* @instance ('MonadBase' b m, 'MonadIO' b) => 'MonadIO' m@
* @instance ('MonadBase' b m, 'MonadReader' r b) => 'MonadReader' r m@
* @instance ('MonadBase' b m, 'MonadRWS' r w s b) => 'MonadRWS' r w s m@
* @instance ('MonadBase' b m, 'MonadState' s b) => 'MonadState' s m@
* @instance ('MonadBase' b m, 'MonadWriter' w b) => 'MonadWriter' w m@
Note that the following instance is not included, as currently it cannot be due to GHC bug #4259:
* @instance ('MonadTransControl' t, 'Monad' (t m), 'MonadBaseControl' b m) => 'MonadBaseControl' b (t m)@
-}
module Control.Monad.Instances.Evil
()
where
import Control.Applicative (Applicative (..))
import Control.Monad.Base (MonadBase (..))
import Control.Monad.Cont.Class (MonadCont(..))
import Control.Monad.Error.Class (MonadError (..))
import Control.Monad.Fix (MonadFix (..), fix)
import Control.Monad.IO.Class (MonadIO (..))
import Control.Monad.Reader.Class (MonadReader (..))
import Control.Monad.RWS.Class (MonadRWS (..))
import Control.Monad.State.Class (MonadState (..))
import Control.Monad.Trans.Class (MonadTrans (..))
import Control.Monad.Trans.Control
( ComposeSt
, MonadBaseControl (..)
, MonadTransControl (..)
, Run
, control
, defaultLiftBaseWith
, defaultRestoreM
)
import Control.Monad.Writer.Class (MonadWriter (..))
------------------------------------------------------------------------------
instance (MonadTrans t, Applicative (t m), Monad (t m), MonadBase b m) => MonadBase b (t m) where
liftBase = lift . liftBase
------------------------------------------------------------------------------
{- This doesn't work, see: http://hackage.haskell.org/trac/ghc/ticket/4259
instance (MonadTransControl t, Monad (t m), MonadBaseControl b m) => MonadBaseControl b (t m) where
newtype StM (t m) a = StMT {unStMT :: ComposeSt t m a}
liftBaseWith = defaultLiftBaseWith StMT
restoreM = defaultRestoreM unStMT
-}
------------------------------------------------------------------------------
instance (MonadTransControl t, Monad (t m), MonadCont m) => MonadCont (t m) where
callCC f = controlT $ \run -> callCC $ \c -> run . f $
\a -> lift (run (return a) >>= c)
------------------------------------------------------------------------------
instance (MonadBaseControl b m, MonadCont b) => MonadCont m where
callCC f = control $ \run -> callCC $ \c -> run . f $
\a -> liftBase (run (return a) >>= c)
------------------------------------------------------------------------------
instance (MonadTransControl t, Monad (t m), MonadError e m) => MonadError e (t m) where
throwError = lift . throwError
catchError t h = controlT $ \run -> catchError (run t) (\e -> run (h e))
------------------------------------------------------------------------------
instance (MonadBaseControl b m, MonadError e b) => MonadError e m where
throwError = liftBase . throwError
catchError t h = control $ \run -> catchError (run t) (\e -> run (h e))
------------------------------------------------------------------------------
instance (MonadTransControl t, Monad (t m), MonadFix m) => MonadFix (t m) where
mfix f = controlT $ \run -> mfix (\a -> run (restoreT (return a) >>= f))
------------------------------------------------------------------------------
instance (MonadBaseControl b m, MonadFix b) => MonadFix m where
mfix f = control $ \run -> mfix (\a -> run (restoreM a >>= f))
------------------------------------------------------------------------------
instance (MonadTrans t, Monad (t m), MonadIO m) => MonadIO (t m) where
liftIO = lift . liftIO
------------------------------------------------------------------------------
instance (MonadBase b m, MonadIO b) => MonadIO m where
liftIO = liftBase . liftIO
------------------------------------------------------------------------------
instance (MonadTrans t, Monad (t m), MonadReader r m) => MonadReader r (t m) where
ask = lift ask
local f m = m >>= lift . local f . return
------------------------------------------------------------------------------
instance (MonadBase b m, MonadReader r b) => MonadReader r m where
ask = liftBase ask
local f m = m >>= liftBase . local f . return
------------------------------------------------------------------------------
instance (MonadTrans t, Monad (t m), MonadRWS r w s m) => MonadRWS r w s (t m)
------------------------------------------------------------------------------
instance (MonadBase b m, MonadRWS r w s b) => MonadRWS r w s m
------------------------------------------------------------------------------
instance (MonadTrans t, Monad (t m), MonadState s m) => MonadState s (t m) where
get = lift get
put s = lift $ put s
------------------------------------------------------------------------------
instance (MonadBase b m, MonadState s b) => MonadState s m where
get = liftBase get
put s = liftBase $ put s
------------------------------------------------------------------------------
instance (MonadTrans t, Monad (t m), MonadWriter w m) => MonadWriter w (t m) where
tell w = lift $ tell w
listen m = m >>= lift . listen . return
pass m = m >>= lift . pass . return
------------------------------------------------------------------------------
instance (MonadBase b m, MonadWriter w b) => MonadWriter w m where
tell w = liftBase $ tell w
listen m = m >>= liftBase . listen . return
pass m = m >>= liftBase . pass . return
------------------------------------------------------------------------------
controlT
:: (MonadTransControl t, Monad (t m), Monad m)
=> (Run t -> m (StT t a)) -> t m a
controlT f = liftWith f >>= restoreT . return