
On Mon, Dec 19, 2011 at 6:37 PM, wren ng thornton
On 12/14/11 10:58 PM, Gregory Crosswhite wrote:
Of course, this is not a simple change at all because it would have to be done in such a way as to respect the ordering of actions --- that is, we can't have each action executed only when the corresponding element of the list demanded is forced, or else actions would undesirably interleave.
Therein lies the issue. To put this in a monadic context, this is the same reason why we can't just say:
evalState (repeatM getNext) init
e.g., to generate an infinite list of pseudorandom numbers and then discard the final seed because we have all the numbers we'll ever need.
Sure you can. Just make sure you're using a non-strict state monad.
import Control.Monad.Identity
import Control.Monad.State.Lazy
import System.Random
repeatM :: Monad m => m a -> m [a]
repeatM = sequence . repeat
nextM :: RandomGen g => StateT g Identity Int
nextM = StateT $ Identity . next
*Main> g <- getStdGen
*Main> let ints = runIdentity $ evalStateT (repeatM nextM) g
*Main> :t ints
ints :: [Int]
*Main> take 5 ints
[1259974427,117524251,96384700,1814821362,997859942]
*Main> take 10 ints
[1259974427,117524251,96384700,1814821362,997859942,2058526379,835643552,1075525457,727974455,388071455]
*Main> ints !! 100
271901956
--
Dave Menendez