<!doctype html public "-//W3C//DTD W3 HTML//EN">
<html><head><style type="text/css"><!--
blockquote, dl, ul, ol, li { padding-top: 0 ; padding-bottom: 0 }
--></style><title>State monad strictness - how?</title></head><body>
<div>I can't seem to figure out how to achieve strictness in the
context of the State monad. Consider:</div>
<div><br></div>
<div><font face="Courier">> import Control.Monad.State</font><br>
<font face="Courier"></font></div>
<div><font face="Courier">> try count = print final</font></div>
<div><font face="Courier">> where (_,final) = runState prog
0<br>
> prog = sequence_
(replicate count tick)<br>
<br>
> tick :: State Int Int<br>
> tick = do n <- get</font></div>
<div><font
face="Courier"
>> put
(n+1)</font></div>
<div><font
face="Courier"
>>
return n</font><br>
<font face="Courier"></font></div>
<div><font face="Courier">(try 1000000)</font> overflows the
stack.</div>
<div><font face="Courier"><br></font></div>
<div>It doesn't help to use:</div>
<div><br></div>
<div><font
face="Courier"
>> put
$! (n+1)</font></div>
<div><font face="Courier"><br></font></div>
<div>The only way I've been able to get the necessary strictness is to
add use of ($!) in the definition of (>>=):</div>
<div><font face="Courier"><br>
> data SState s a = SState (s -> (a,s))<br>
> instance Monad (SState s) where<br>
> return x = SState (\s -> (x,s))<br>
> m >>= f = SState (\s -> let SState m' =
m<br>
> <span
></span
> <span
></span> (x,s1)
= m' s<br>
> <span
></span
> <span
></span> SState
f' = f x<br>
> <span
></span
> <span
></span> (y,s2)
= f' $! s1<br>
> <span
></span
> <span
></span> in (y,s2))<br>
> runSState (SState m) s = m s<br>
> sget = SState (\s -> (s,s))<br>
> sput s' = SState (\s -> ((),s'))<br>
<br>
> stry count = print final<br>
> where (_,final) = runSState prog 0<br>
> prog = sequence_
(replicate count stick)<br>
<br>
> stick :: SState Int Int<br>
> stick = do n <- sget<br>
>
sput (n+1)</font></div>
<div><font
face="Courier"
>>
return n</font></div>
<div><font face="Courier"><br></font></div>
<div>Is there no way to get strictness using the standard State
monad?</div>
<div><br></div>
<div>Dean</div>
</body>
</html>