@Cirdec's solution certainly works, but it has a possible problem: it nests >>= deep to the left. For many (but not for all!) Monads, this can lead to a stack break similar to using a foldl . Therefore, I will present another solution, which instead of >>= will be placed on the right. For monads, such as IO , this should allow you to build an action and consume lazily from the card as it progresses.
This solution is probably a little more complicated as it uses the correct fold to create a monadic function that will eventually consume the initial value. At least I had problems with the correct types.
With the exception of key processing, this is essentially the same method that Data.Foldable.foldlM uses.
source share