{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, UndecidableInstances, FlexibleInstances #-}

-----------------------------------------------------------------------------
-- Module      :  Control.Monad.RWSX.Class
-- Copyright   :  (c) Mark Snyder 2008.
-- License     :  BSD-style
-- Maintainer  :  Mark Snyder, marks@ittc.ku.edu
-- Stability   :  experimental
-- Portability :  non-portable (multi-param classes, functional dependencies)
-----------------------------------------------------------------------------

module Control.Monad.RWSX.Class (

    MonadRWSX,

    module Control.Monad.Reader.Class,
    module Control.Monad.State.Class,
    module Control.Monad.Writer.Class,

    module Control.Monad.ReaderX.Class,
    module Control.Monad.StateX.Class,
    module Control.Monad.WriterX.Class,

  ) where

import Control.Monad.Reader.Class
import Control.Monad.State.Class
import Control.Monad.Writer.Class
import Data.Monoid

import Control.Monad.Index
import Control.Monad.ReaderX.Class
import Control.Monad.StateX.Class
import Control.Monad.WriterX.Class


import Control.Monad.Reader
import Control.Monad.State
import Control.Monad.Writer
import Control.Monad.RWS

import Control.Monad.ReaderX()
import Control.Monad.StateX()
import Control.Monad.WriterX()



class (Monoid w, Index ix, MonadReaderX ix r m, MonadWriterX ix w m, MonadStateX ix s m)
   => MonadRWSX ix r w s m | ix m -> r, ix m -> w, ix m -> s


----------------------------------------------------------------
-- instances for other monads.  Since we have no functions to
-- implement, we do not need to distinguish between strict and lazy
-- versions.


-- Reader
instance (Monoid w1, Index ix1
         ,MonadRWSX ix1 r1 w1 s1 m
         )
   => MonadRWSX ix1 r1 w1 s1 (ReaderT r2 m) where


-- Writer
instance (Monoid w1, Monoid w2, Index ix1
         ,MonadRWSX ix1 r1 w1 s1 m
         )
   => MonadRWSX ix1 r1 w1 s1 (WriterT w2 m) where


-- State
instance (Monoid w1, Index ix1
         ,MonadRWSX ix1 r1 w1 s1 m
         )
   => MonadRWSX ix1 r1 w1 s1 (StateT s2 m) where


-- RWS
instance (Monoid w1, Monoid w2, Index ix1
         , MonadRWSX ix1 r1 w1 s1 m
         )
    => MonadRWSX ix1 r1 w1 s1 (RWST r2 w2 s2 m) where