$Id: MonadEnvironment.lhs,v 1.5 2004/10/18 23:47:48 leavens Exp leavens $

The environment monad.  See Philip Wadler's paper
"The Essence of Functional Programming", POPL 1992, pages 1-14.

> module MonadEnv where
> import Domains
> import Environments
> import List

> type Identifier = String
> type DenotableValue = ExpressibleValue
> type Environment = FiniteFun Identifier DenotableValue

> data MEnv t = Env (Environment -> t)

> instance Monad MEnv where
>    (Env f) >>= k = Env (\env -> let v = f env
>                                     (Env g) = k v
>                                 in g env)
>    return v = Env (\env -> v)

In Haskell 1.4 we had the following:

 instance MonadZero MEnv where
    zero = Env (\s -> error "semantic error")

but this is no loger needed

> class Monad m => EnvMonad m where
>    lookupE :: Identifier -> m DenotableValue
>    closeWithE :: formals -> body -> m (formals, body, Environment)
>    readE :: m Environment
>    inE :: Environment -> m t -> m t
>    scopeE :: [Identifier] -> [DenotableValue] -> Environment -> m t -> m t
>    addToE :: [Identifier] -> [DenotableValue] -> m t -> m t

> instance EnvMonad MEnv where
>    lookupE id = Env (\env -> env `dot` id)
>    closeWithE formals body = Env (\env -> (formals, body, env))
>    readE = Env (\env -> env)
>    inE env (Env f) = Env (\_ -> f env)
>    scopeE ids dvs old_env m =
>      (case bind ids dvs of
>         (Just bs) -> inE (old_env `unionMinus` bs) m
>         Nothing -> error "duplicate names")
>    addToE ids dvs m =
>      do env <- readE
>         scopeE ids dvs env m


> instance Show t => Show (MEnv t) where
>    showsPrec p (Env f) = let v = f []
>                          in showsPrec p v
