我正在使用免费的单子和镜头,使用免费的单子来创建我自己的 IO 单子版本:
data MyIO next
= LogMsg String next
| GetInput (String -> next)
deriving (Functor)
我将它堆叠在一个状态单子的顶部,如下所示:FreeT MyIO (State GameState) a
哪里GameState
是:
data GameState = GameState { _players :: [PlayerState] }
现在,我想要的是一种PlayerState
从GameState
上下文“放大” a 的方法。像这样的东西:
zoomPlayer :: Int -> FreeT MyIO (State PlayerState) a -> FreeT MyIO (State GameState) a
zoomPlayer i prog = hoistFreeT (zoom (players . element i)) prog
但我收到了这个错误:
No instance for (Data.Monoid.Monoid a1)
arising from a use of ‘_head’
players . element i
这个错误似乎与遍历的事实有关;如果我从中删除列表方面_players
并使用普通镜头,那么代码就可以工作。
关于如何编写这个函数的任何想法?