Implementing RefMonads in Haskell without ST,IO

Derek Elkins ddarius@hotpop.com
Fri, 30 May 2003 01:32:32 -0400


On Fri, 30 May 2003 00:00:26 -0500
"Tim Sweeney" <tim@epicgames.com> wrote:

> Hi Derek,
> 
> How can one implement RefMonad below directly in Haskell?
> 
> class Monad m => RefMonad m r | m -> r where
>     newRef :: a -> m (r a)
>     readRef :: r a -> m a
>     writeRef :: r a -> a -> m ()
> 
> I've been able to implement a monad that encapsulates "references to
> integers", by creating a monad that passes "the heap" (a function
> int->int, from heap indices to integer values stored in the heap) in
> and out of functions.  That was pretty straightforward, and the monad
> makes everything look like an imperative language that supports
> updatable references to integers (and only integers).
> 
> But how can one implement RefMonad to support references of all
> possible types simultaneously?

There isn't without an unsafe coerce function.  However, you can get all
the types that are an instances of a class, e.g. Typeable.  As Hal Daume
said, you can use Dynamics.  GHC's implementation does use an
unsafeCoerce function but "A Lightweight Implementation of Generics and
Dynamics" (or something very close to that) shows that such a function
is unnecessary and only existential quantification is needed to make
Dynamics.  If you want to be able to change the type you store in/at a
reference then this is your only real option.  However, likely you want
typed references.  Dynamics seems unnecessary/overkill for this (though
it may be). You know what type you want, you aren't going to mistake it,
so you shouldn't need to carry around a TypeRep.

Anyways, you may want to check out "A Lightweight Implementation...", it
has some interesting type stuff that may give you ideas.