{-# LANGUAGE TypeFamilies, NoMonomorphismRestriction, NoImplicitPrelude, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, UndecidableInstances #-}

module Control.RMonad.Trans.Reader where

import Prelude hiding (return, fail, (>>=), (>>), (=<<), sequence, sequence_, mapM, mapM_)

import Control.RMonad
import Control.RMonad.Trans

import Data.Suitable

import Control.Monad.Trans.Reader

instance Suitable m a => Suitable (ReaderT r m) a where
   data Constraints (ReaderT r m) a = Suitable m a => ReaderTConstraints
   constraints _ = ReaderTConstraints

instance RMonad m => RMonad (ReaderT r m) where
   return a = withResConstraints $ \ReaderTConstraints -> ReaderT $ const (return a)
   m >>= f = withResConstraints $ \ReaderTConstraints -> withConstraintsOf m $ \ReaderTConstraints ->
             ReaderT $ \v -> do a <- runReaderT m v
                                runReaderT (f a) v

instance RMonadTrans (ReaderT r) where
  lift m = withResConstraints $ \ReaderTConstraints -> ReaderT $ const m

instance RMonadIO m => RMonadIO (ReaderT r m) where
  liftIO m = withResConstraints $ \ReaderTConstraints -> lift $ liftIO m