module MonadLab.Env (
envT
) where
import Prelude hiding (Monad)
import Language.Haskell.TH
import MonadLab.CommonTypes
envT :: Layer -> MonadTransformer
envT l@(EnvT name t0) = \m -> ( envTransTypeCon t0 m
, envTransReturn m
, envTransBind m
, envTransLayerNPM l m : envTransLiftLayerNPMs m
, [| $envTransLift . $(getBaseLift m) |]
)
envTransTypeCon :: TypeQ -> Monad -> MonadTypeCon
envTransTypeCon r m = let tc = getTypeCon m
in \t -> arrow r (tc t)
envTransReturn :: Monad -> ReturnExpQ
envTransReturn m = let return = getReturn m
in [| \v -> \r -> $return v |]
envTransBind :: Monad -> BindExpQ
envTransBind m = let bind = getBind m
in [| \m -> \f -> \r -> $bind (m r) (\v -> f v r) |]
envTransRdEnv :: Monad -> NonProperMorphismExpQ
envTransRdEnv m = let return = getReturn m
in [| \r -> $return r |]
envTransInEnv :: NonProperMorphismExpQ
envTransInEnv = [| \r -> \m -> \_ -> m r |]
envTransLift :: LiftExpQ
envTransLift = [| \m -> \r -> m |]
envTransLayerNPM :: Layer -> Monad -> LayerNPM
envTransLayerNPM l m = (l, [envTransRdEnv m, envTransInEnv])
envTransLiftLayerNPMs :: Monad -> [LayerNPM]
envTransLiftLayerNPMs m = map (envTransLiftLayerNPM m) (getLayerNPMs m)
where envTransLiftLayerNPM :: Monad -> LayerNPM -> LayerNPM
envTransLiftLayerNPM m l = case l of
(Io, [liftIO]) -> (Io, [envTransLiftLiftIO liftIO])
(List, [merge, halt]) -> (List, [envTransLiftMerge m, envTransLiftHalt m])
(StateT n t, [get,put]) -> (StateT n t, [envTransLiftGet get, envTransLiftPut put])
(EnvT n t, [rdEnv,inEnv]) -> (EnvT n t, [envTransLiftRdEnv rdEnv, envTransLiftInEnv inEnv])
(ErrorT n t, [throw,catch]) -> (ErrorT n t, [envTransLiftThrow throw, envTransLiftCatch catch])
(WriterT n t, [tell, listen, pass]) -> (WriterT n t, [envTransLiftTell tell, envTransLiftListen m listen, envTransLiftPass m pass])
(ContT t, [callcc]) -> (ContT t, [envTransLiftCallCC m callcc])
envTransLiftRdEnv :: NonProperMorphismExpQ -> NonProperMorphismExpQ
envTransLiftRdEnv rdEnv = [| $envTransLift $rdEnv |]
envTransLiftInEnv :: NonProperMorphismExpQ -> NonProperMorphismExpQ
envTransLiftInEnv inEnv = [| \r -> \m -> \r' -> $inEnv r (m r') |]
envTransLiftGet :: NonProperMorphismExpQ -> NonProperMorphismExpQ
envTransLiftGet get = [| $envTransLift $get |]
envTransLiftPut :: NonProperMorphismExpQ -> NonProperMorphismExpQ
envTransLiftPut put = [| $composition $envTransLift $put |]
envTransLiftThrow :: NonProperMorphismExpQ -> NonProperMorphismExpQ
envTransLiftThrow throw = [| $composition $envTransLift $throw |]
envTransLiftCatch :: NonProperMorphismExpQ -> NonProperMorphismExpQ
envTransLiftCatch catch = [| \m -> \h -> \r -> $catch (m r) (\e -> h e r) |]
envTransLiftMerge :: Monad -> NonProperMorphismExpQ
envTransLiftMerge m = let newJoin = [| \x -> $(envTransBind m) x (\a -> a) |]
newBaseLift = [| $envTransLift . $(getBaseLift m) |]
in [| $composition $newJoin $newBaseLift |]
envTransLiftHalt :: Monad -> NonProperMorphismExpQ
envTransLiftHalt m = let newBaseLift = [| $envTransLift . $(getBaseLift m) |]
in [| $newBaseLift [] |]
envTransLiftLiftIO :: NonProperMorphismExpQ -> NonProperMorphismExpQ
envTransLiftLiftIO liftIO = [| $envTransLift . $liftIO |]
envTransLiftTell :: NonProperMorphismExpQ -> NonProperMorphismExpQ
envTransLiftTell tell = [| $composition $envTransLift $tell |]
envTransLiftListen :: Monad -> NonProperMorphismExpQ -> NonProperMorphismExpQ
envTransLiftListen m listen = let return = getReturn m
bind = getBind m
in [| \m -> \r -> $listen (m r) |]
envTransLiftPass :: Monad -> NonProperMorphismExpQ -> NonProperMorphismExpQ
envTransLiftPass m pass = let return = getReturn m
bind = getBind m
in [| \m -> \r -> $pass (m r) |]
envTransLiftCallCC :: Monad -> NonProperMorphismExpQ -> NonProperMorphismExpQ
envTransLiftCallCC m callcc = [| \f -> \r -> $callcc (\k -> f (\a -> \r' -> k a) r) |]