Josef Svenningsson wrote:
Take the state monad for example. Should it be
strict or lazy in the state that it carries
around? What about the value component?
...both strict and lazy variants are useful.

I wrote:
Are those really needed?

...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.

I don't think that is so inconvenient. Why do we
need to define getStrict, putStrict, getsStrict,
etc., when it is perhaps even more clear to write
get $!, put $!., (gets . ($!)), etc.?.

The same goes for Iavor's monad 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.

I am now pretty convinced that the only thing we
need is two versions of each monad, varying only
the strictness of >>=.

Then, of course, we will need runFoo for each, and
evalFoo and execFoo for each state monad.

And adaptors that allow you to run a lazy
calculation inside a strict one and vice-versa. So
we need an asStrict function and an asLazy
function for each lazy/strict pair of monads.

I think that is all we need. Not too bad.

I am very impressed that we get most of that
almost for free in Iavor's library.

The same challenge exists in many of the Data.*
libraries. I think this is very important.

I am now a bit more optimistic. Has anyone looked
through them?

http://www.cs.chalmers.se/~josefs/monadlib/
...instantiating this with different pair types
with different strictness properties will give
us total control over strictness for state and
value.

Hmm. Your current implementation doesn't seem to
do it that way. You use tuples for both the lazy
version and the strict version, and each defines
its own Monad instance for all Pair types. So it
is impossible to use both in the same module, even
with hiding.

I tried to work on this a little. I defined a
strict Pair type and tried to find a single Monad
instance that will give the right strictness for
both if you just vary between lazy and strict
pairs.

We need that both of the following converge
in constant stack space:

take 100 $ evalState (repeatM $ modify (+1)) 0
execStateStrict (replicateM_ 100000 $ modify (+1)) 0

(You can verify that this is true if you use the
standard evalState, and replace execStateStrict
with runIdentity . execStateT.)

I was unable to hit upon the right combination of
seqs in the Monad instance. Is it really possible?

Of course, you could use a newtype of tuples and
define separate Monad instances. But then we are
not gaining anything over just defining the lazy
and strict monads directly.

Regards,
Yitz
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to