
Would unsafeInterleaveST work just as unsafeInterleaveIO in the manner
that it returns immediately, and then is computed lazily?
The idea in the complete program is that one part representing
the CPU will produce a list lazily, which will then be consumed
lazily by another part of the program, which in turn will produce
a lazy list fed to the CPU.
I might add that there was a base case for foo. It turns out i omitted
that for "simplicity". Even stranger, if one adds the following
foo y = do
if something then return y
else do
val <- foo (y+1)
fail "this is a fail"
Will make the program fail with "this is a fail". Without the fail, that
does not return the computed y. How come?
//Tobias
2009/5/4 Ryan Ingram
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
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@wobsi]$ ./runnerLazy looper.hex runnerLazy: <<loop>>
The very same program compiled with ST.Strict outputs: [tobsi@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@gmail.com _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Tobias Olausson tobsan@gmail.com