[Haskell-cafe] ST.Lazy vs ST.Strict

Ryan Ingram ryani.spam at gmail.com
Sun May 3 18:11:17 EDT 2009


So, I don't know what is causing your problem, but foo will not do
what you want even with lazy ST.

foo y = do
   x <- something
   xs <- foo (y+1)
   return (x:xs)

Desugaring:

foo y = something >>= \x -> foo (y+1) >>= \xs -> return (x:xs)
= something >>= \x -> something >>= \x2 -> foo (y+2) >>= \xs2 ->
return (x2:xs2) >>= \xs -> return (x:xs)
= something >>= \x -> something >>= \x2 -> foo (y+2) >>= \xs2 ->
return (x:x2:xs2)

You see that there is an infinite chain of "foo" calls; the lazy ST
still needs to thread the state through that chain; so in the case of
foo 0 >>= something_else, the state is _|_ for something_else and you
will fail if you use read/write/newSTRef after that point.  In fact,
I'm not sure that lazy ST is very useful :)

My guess is that you want one of
(1) mdo, when the effects in 'something' only matter once, or
(2) unsafeInterleaveST, if you just want to be able to traverse the
(x:xs) list lazily and the references it uses are dead after calling
foo.

  -- ryan

On Sun, May 3, 2009 at 10:27 AM, Tobias Olausson <tobsan at gmail.com> wrote:
> Hello!
> I have a program that is using ST.Strict, which works fine.
> However, the program needs to be extended, and to do that,
> lazy evaluation is needed. As a result of that, I have switched
> to ST.Lazy to be able to do stuff like
>
> foo y = do
>    x <- something
>    xs <- foo (y+1)
>    return (x:xs)
>
> However, when running the program compiled with ST.Lazy, the
> following is outputted:
>   [tobsi at wobsi]$ ./runnerLazy looper.hex
>   runnerLazy: <<loop>>
>
> The very same program compiled with ST.Strict outputs:
>   [tobsi at wobsi]$ ./runner looper.hex
>   83298556
>
> The code that is actually computing stuff is this:
> loopSys :: Int -> CPU s Int
> loopSys cc = do
>    instr <- fetch
>    if instr == 0xEA --NOP
>       then return cc
>       else do
>         c <- execute instr
>         loopSys $! (cc+c)
>
> The CPU type looks as follows:
>   type CPU s a = ReaderT (SysEnv s) (ST s) a
>
> The program is run like
>   runReaderT (loopSys 0)
> which in turn is being runST'd and then printed
>
> Does anyone know why the program just outputs <<loop>>
> when compiled under ghc 6.10.2, and runs perfectly fine
> under ghc 6.8.2? The program is compiled with --make and -O2
>
>
> Tobias Olausson
> tobsan at gmail.com
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>


More information about the Haskell-Cafe mailing list