I cheat with free monads and a lens, using the free monad to create my own version of the IO monad:
data MyIO next = LogMsg String next | GetInput (String -> next) deriving (Functor)
I put this on top of the state monad like this: FreeT MyIO (State GameState) a where GameState :
data GameState = GameState { _players :: [PlayerState] }
Now, what I would like is a way to "zoom in" a PlayerState from the context of a GameState . Something like that:
zoomPlayer :: Int -> FreeT MyIO (State PlayerState) a -> FreeT MyIO (State GameState) a zoomPlayer i prog = hoistFreeT (zoom (players . element i)) prog
But I get this error:
No instance for (Data.Monoid.Monoid a1) arising from a use of '_head'
This error seems to be related to what players . element i players . element i - bypass; if I _players list aspect from _players and use a regular lens, then the code works.
Any ideas on how to write this feature?
source share