My data structure looks more or less like this (simplified for the purpose of the question)
data GameObject = GameObject { _num :: Int }
data Game = Game { _objects :: [GameObject] }
I use makeLenses
to generate the accessors for both of those. Thus, I am able to do operations en masse like this:
-- loop :: MonadState with Game inside
loop = objects.traversed.num += 1
And this is great.
However, I can't find a way to do an equivalent of this (printing every num
):
game <- get
let objects = _objects game
let objectNums = map _num objects
mapM_ print objectNums
I have tried things like
uses (objects.traversed.num) >>= mapM_ print
but the only way I see to use traversed
with some state like that involves using monoids, and I don't want to combine the fields; I want to run a monadic action over a part of every element in the elements from some sequence that resides in my state.
So, is this possible using some provided Lens function or do I have to write that myself, somehow?
What about
mapMOf_ (objects . traversed . num) print
or if you want to apply that to the state of a state monad,
get >>= mapMOf_ (objects . traversed . num) print
? (Perhaps there's a more lens-like way to combine the first line with the state of a state monad. If so, I'd like to learn about it myself.)