$Id: MonadStore.lhs,v 1.7 1999/10/07 14:30:36 leavens Exp leavens $

The store monad, adapted from Philip Wadler's paper
"The Essence of Functional Programming", POPL 1992, pages 1-14, section 2.5.

> module MonadStore where
> import Domains

This monad is specific to the domains DLocation, DStore,
and StorableValue found in the module Domains.
Without these dependencies, it's impossible (it seems)
to get reasonable types for the StoreMonad class's methods.
In any case, this is just a front for the stores in Domains.

> data MStore t = Store (DStore -> (t, DStore))

Note the the monadic operators are made strict, to
ensure that semantic functions written using them are strict.

> instance Monad MStore where
>    (Store f) >>= k = Store (\s0 -> let (v, s1) = $! f s0
>                                        (Store g) = k v
>                                    in $! g s1)
>    return v = Store (\s0 -> s0 `seq` (v, s0))

> instance MonadZero MStore where
>    zero = Store (\s -> error "type error")

> class Monad m => StoreMonad m where
>    lookupS :: DLocation -> m StorableValue
>    updateS :: DLocation -> StorableValue -> m ()
>    allocateS :: m DLocation

> instance StoreMonad MStore where
>    lookupS l =
>       Store (\s -> (lookupStore(l, s), s))
>    updateS loc val =
>       Store (\s -> ((), updateStore(loc, val, s)))
>    allocateS = 
>       Store (\s -> allocateStore s)


> instance Show t => Show (MStore t) where
>    showsPrec p (Store f) = let (v, s) = f emptyStore
>                            in showsPrec p v
