Proposal: Make StateT in mtl lazy

Ian Lynagh igloo at
Wed Jan 31 10:48:25 EST 2007

On Tue, Jan 30, 2007 at 04:58:48PM +0000, Ian Lynagh wrote:
> I propose we make StateT lazy

SimonM writes:

> I don't mind whether StateT itself is lazy or not, but I think we
> should have a strict version. In GHC the implementation should use
> unboxed tuples, like IO.

If we're going to have a strict StateT then it would make sense to have
a strict State too. Control.Monad.State.Strict perhaps? (and likewise
for the other mtl monads, where appropriate).

Or perhaps go a bit further and have:

Control.Monad.State.Class -- for the MonadState class
Control.Monad.State -- re-exports .Class and .Lazy

There's perhaps an argument for splitting the package into mtl-classes,
mtl-lazy and mtl-strict but I think that that would be overkill at this

There's going to be a lot of duplication between the lazy and strict
(and GHC) variants, but short of some hideous CPP I don't think there's
a nice solution.

By "strict", do you mean this?:

instance Monad (State s) where
    return a = State $ \s -> (a, s)
    m >>= k  = State $ \s -> case runState m s of
                             (a, s') -> runState (k a) $! s'

instance (Monad m) => Monad (StateT s m) where
    return a = StateT $ \s -> return (a, s)
    m >>= k  = StateT $ \s -> do
        (a, s') <- runStateT m s
        runStateT (k a) $! s'
    fail str = StateT $ \_ -> fail str


More information about the Libraries mailing list