$Id: MonadStore.lhs,v 1.8 2004/10/18 23:47:48 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))

In Haskell 1.4 we had the following:

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

but this is no loger needed

> 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
