[Haskell-beginners] Randomness, lists, and unfoldr

Daniel Fischer daniel.is.fischer at web.de
Mon Sep 13 15:21:42 EDT 2010


On Monday 13 September 2010 20:42:49, Alex Rozenshteyn wrote:
> I'm trying to build a list where each entry depends on the previous one.
> Unfoldr seemed like a good idea at the time.
> Unfortunately, my values are monadic values (specifically RVars, from
> the random-fu package).  Okay, shouldn't be a problem; I just monadic
> bind and...
>
> > -- example code
> > updateCell :: Bool -> RVar Bool
> > updateCell False = return False
> > updateCell True  = bernoulli (0.9 :: Double)
> >
> > sim = sequence $ take 20 $ unfoldr (\x -> Just (x, x >>= updateCell))
>
> (return True)

So you get

sequence [return True
    , return True >>= updateCell
    , (return True >>= updateCell) >>= updateCell
    , ((return True >>= updateCell) >>= updateCell) >>= updateCell
    , ... ]

>
> > runRVar sim DevURandom
>
> [True,True,True,True,True,False,True,False,True,False,False,False,False,
>False,False,True,True,False,False,False]
>
> That output shouldn't be possible if I'm doing things right...  It
> appears that each cell has an independent history.  I'm stumped.
> Advice on threading monad input in general and random-fu in specific
> would be appreciated.

What you want would be something like

iterateM :: (Monad m) => (a -> m a) -> a -> m [a]
iterateM act start = do
    next <- act start
    rest <- iterateM act next
    return (start : rest)

but that would only work if the bind is sufficiently lazy, otherwise you'd 
have to iterate a given number of times.



More information about the Beginners mailing list