Is there a way to take a given monad's bind and wrap it to make it more lazy?  It doesn't seem like there should be, but I'm being hopeful.

On Mon, Sep 13, 2010 at 3:21 PM, Daniel Fischer <daniel.is.fischer@web.de> wrote:
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.




--
          Alex R