[Haskell-cafe] State monad strictness - how?

Josef Svenningsson josef.svenningsson at gmail.com
Wed Jan 10 10:10:45 EST 2007

On 1/10/07, Yitzchak Gale <gale at sefer.org> wrote:
> Hi Josef,
> Josef Svenningsson wrote:
> > ...the fun doesn't end there. There are other strictness properties
> > to consider.
> Could be. But after using mtl heavily for a few years now,
> I find that in practice the only one where have felt the need
> for control over strictness is >>=, like Dean's example.
Yes. For most uses this finer control of strictness is just overkill.
But in the rare cases when you really need this tweakability then it's
a royal pain if you don't have it.

> > Take the state monad for example. Should it be strict or
> > lazy in the state that it carries around? What about the value
> > component? I think the answer to these questions are the same as for
> > monadic strictness above: both strict and lazy variants are useful.
> Are those really needed? Can't the strictness of the state be
> fully controlled by seq with runState, get, and put, and by
> choosing lazy or strict >>=? And similarly with value?
Yes, you're right. But it wouldn't be very convenient, would it?
Sometimes I find that I want strict state by default and then I don't
want to sprinkle my code with seqs. Furthermore this extra level of
control is not that difficult to implement in a library.

> > Now, the challenge here is to design a library which doesn't explode
> > in size from all the various possibilities for strictness or laziness.
> The same challenge exists in many of the Data.* libraries.
> I think this is very important.

> > In fact I did once bite the bullet and came up with a library that
> > does all this. Though I haven't released it publicly yet. I never took
> > the time to polish the code to the point where I wouldn't be
> > embarrassed about showing it to others.
> > If you kick me hard enough I might release the library.
> My boot is not long enough :). But I would love to see
> what you did.
:-) Ok, I've put some files under the following url:

It might need some explanation since I use the module system quite
heavily. For a monad such as the state monad the hierarchy looks like
* Control.Monad.State.Base contains the type declaration and basic
  functionality, but NOT instances of the monad class.
  This module is not exposed.
* Control.Monad.State.Lazy
* Control.Monad.State.Strict
  Contains instances for monad classes.
* Control.Monad.State is supposed to be the default and just reexports

Furthermore, again taking the state monad as example, the monad is
parameterized on the type of pair used in the definition of the monad.
So instead of:
newtype State s a = State { runState :: (s -> (a, s)) }
we have:
newtype StateP p s a = StateP { runStateP :: (s -> p a s) }

Now, instantiating this with different pair types with different
strictness properties will give us total control over strictness for
state and value. Data.Pair provides various pair for this purpose.



More information about the Haskell-Cafe mailing list