I have seen the solutions using iterate or replicate in order to apply a function n times. However, I don’t manage to use it inside a State monad.
This code works:
-- Stuff an empty game level with obstacles.
generateLevel :: Level -> State StdGen Level
generateLevel lvl =
placeRandomWall lvl >>= placeRandomWall >>= placeRandomWall
This one works as well, unsurprisingly:
generateLevel :: Level -> State StdGen Level
generateLevel lvl =
placeRandomWall =<< placeRandomWall =<< placeRandomWall lvl
However, this is not the same as:
generateLevel :: Level -> State StdGen Level
generateLevel lvl =
(placeRandomWall =<< placeRandomWall =<< placeRandomWall) lvl
The latest complains about types. Therefore, I can’t foldl (=<<) id (relicate 42 placeRandomWall), nor can I iterate.
This makes sense, as iterate take a a -> a function, while what I have is a -> m a or something like that. So, I don’t really know how to go from there.
I think you’re looking for
<=<and>=>fromControl.Monad. They can be folded across a list you’ve made withreplicateto create one big action.Try
foldr (<=<) return (replicate 42 placeRandomWall).