{-# OPTIONS -fno-warn-orphans #-}
{-# LANGUAGE TypeFamilies, NoMonomorphismRestriction, NoImplicitPrelude, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, UndecidableInstances #-}
{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__>=700
{-# LANGUAGE RebindableSyntax #-}
#endif

module Control.RMonad.Trans.Reader where

import Control.RMonad.Prelude

import Control.RMonad.Trans

import Data.Suitable

import Control.Monad.Trans.Reader

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

instance Suitable m a => Suitable (ReaderT r m) a where
   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