
I can't seem to figure out how to achieve strictness in the context of the State monad. Consider:
import Control.Monad.State
try count = print final where (_,final) = runState prog 0 prog = sequence_ (replicate count tick)
tick :: State Int Int tick = do n <- get put (n+1) return n
(try 1000000) overflows the stack. It doesn't help to use:
put $! (n+1)
The only way I've been able to get the necessary strictness is to add use of ($!) in the definition of (>>=):
data SState s a = SState (s -> (a,s)) instance Monad (SState s) where return x = SState (\s -> (x,s)) m >>= f = SState (\s -> let SState m' = m (x,s1) = m' s SState f' = f x (y,s2) = f' $! s1 in (y,s2)) runSState (SState m) s = m s sget = SState (\s -> (s,s)) sput s' = SState (\s -> ((),s'))
stry count = print final where (_,final) = runSState prog 0 prog = sequence_ (replicate count stick)
stick :: SState Int Int stick = do n <- sget sput (n+1) return n
Is there no way to get strictness using the standard State monad? Dean
participants (1)
-
Dean Herington