IO StateTransformer with an escape clause

Andrew J Bromage ajb@spamcop.net
Wed, 27 Aug 2003 18:23:19 +1000


G'day all.

On Tue, Aug 26, 2003 at 02:33:28PM +1000, Thomas L. Bevan wrote:

> I'd like some help building an IO StateTransformer which can be
> escaped midway through without losing the state accummulated up to
> that point.

A simple way to do this is to use a ReaderT monad stacked on top of IO,
where the reader state is an IORef to whatever your "real" state is, then
write wrapper functions to access the IORef like a state monad.

For example, if you had:

	newtype PersistentStateT s m a
	  = PersistentStateT (ReaderT (IORef s) m a)

then you could write:

	-- WARNING: Unchecked code follows!

	instance (MonadIO m) => MonadState s (PersistentState s m) where
	    get   = PersistentStateT $ do
			r <- ask
			liftIO (readIORef r)

	    set s = PersistentStateT $ do
			r <- ask
			liftIO (writeIORef r s)

The drawback is that the state is no longer backtrackable, say, if you
use a nondeterminism monad transformer stacked over this.

Cheers,
Andrew Bromage