PosMonad implements Pos monad and PosT monad transformer that provides actions declared in MonadPos interface.
> {-# LANGUAGE GeneralizedNewtypeDeriving
> , FlexibleInstances, MultiParamTypeClasses #-}
> {-# OPTIONS_GHC -fallow-undecidable-instances #-}
>
> module PosMonad (
> module PosMonadClass
> , module PosMonad
> ) where
>
> import qualified Control.Monad.Error as E
> import qualified Control.Monad.Identity as I
> import qualified Control.Monad.Trans as T
> import qualified Control.Monad.State as S
> import qualified Control.Monad.Reader as R
> import qualified Control.Monad.Writer as W
> import qualified Control.Monad as M
> import qualified Text.ParserCombinators.Parsec as P
>
> import PosMonadClass
> import TIMonad
> import EvalMonad
> import Error
>
> newtype Pos a = Pos {
> runPos :: PosT I.Identity a
> } deriving (Monad, Functor
> , S.MonadState P.SourcePos
> , MonadPos)
Pos is built using PosT.
> newtype PosT m a = PosT {
> runPosT :: (S.StateT P.SourcePos m) a
> } deriving (Monad, Functor, S.MonadState P.SourcePos
> , R.MonadReader r, W.MonadWriter w, E.MonadError e
> , T.MonadIO)
PosT is built using StateT SourcePos. PosT derives many classes so that it doesn't need to lift explicitly.
> instance T.MonadTrans PosT where
> lift m = PosT (T.lift m)
>
> instance (Monad m) => MonadPos (PosT m) where
> setSourcePos pos = S.put pos
> getSourcePos = S.get
PosT m is an instance of MonadPos. And implementation of setSourcePos and getSourcePos is just delegation to State actions: put and get.
> instance (MonadTI m) => MonadTI (PosT m) where
> getSubst = T.lift getSubst
> putSubst = T.lift . putSubst
> extendSubst = T.lift . extendSubst
> newId = T.lift newId
> getN = T.lift getN
> putN = T.lift . putN
>
> instance (MonadEval m) => MonadEval (PosT m) where
> getEnv = T.lift getEnv
> getEnvs = T.lift getEnvs
> putEnvs = T.lift . putEnvs
> pushEnv = T.lift . pushEnv
> popEnv = T.lift popEnv
Above instances enable magic lift. In PostT m monad, one can use setSourcePos, getSubst, getEnv...etc without explicit lift.