On Mon, Dec 19, 2011 at 6:37 PM, wren ng thornton <[email protected]> wrote:
> 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 <[email protected]>
<http://www.eyrie.org/~zednenem/>

_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to