How can I use Lenses to perform read-only monadic operation over a sequence held in some state?
haskell, haskell-lens
Solution
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.)
Problem
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?