 I’ve got some code that I brute forced like this:

``````do
let i1 = 0
i2 <- fn i1
i3 <- fn i2
i4 <- fn i3
i5 <- fn i4
pure [i1, i2, i3, i4, i5]
``````

or

``````  let i1 = 0
in
fn i1 >>= \i2 ->
fn i2 >>= \i3 ->
fn i3 >>= \i4 ->
fn i4 >>= \i5 ->
pure [i1, i2, i3, i4, i5]
``````

but with even more iterations than that. Clearly, it calls for some sort of loop, but I’m having a tough time though figuring out how to do that when I’m inside a monad already. I think it would just be a fold over `>>= fn` if I could throw away the value at each iteration, but then I can’t see how to assemble the answer at the end. Any pointers?

take a look at `foldM`

Ah, thank you! That’s the pointer I needed to get unstuck. I used it to arrive at a solution:

``````  reverse . toList <\$> foldM foldFn (0 :| []) [1 .. n]

where
foldFn (i' :| is) _elem = do
i <- fn i'
pure (i :| i':is)
``````

but then I played with it some more and figured out how to solve it with recursion so I could do a right fold instead of left:

``````  (0:) <\$> go 0 iterations
where
go _ 0 = pure []
go i n = do
i' <- fn i
(i':) <\$> go i' (n-1)
``````