用于州管理的游戏编程中的优雅镜头(mtl风格)

时间:2018-04-04 15:13:13

标签: haskell

在我的游戏中,我使用全局GameState,其中包含PlayerState列表。球员数量是动态的。

data PlayerState = PlayerState {
  _playerState_Id   :: Int,
  _playerState_Cash :: Int
                               }
data GameState = GameState {
  _gameState_CurrentPlayer :: Int,
  _gameState_PlayerStates  :: [PlayerState]
                           }

makeClassy ''PlayerState
makeClassy ''GameState

instance HasPlayerState GameState where
  playerState_Id = gameState_PlayerStates . ix 0 . Id
  playerState_cash = gameState_PlayerStates . ix 0 . cash

我的目标是更新StateT monad中的这些字段,其功能如下所示:

update :: (MonadIO m,
           MonadState s m,
           HasPlayerState s,
           HasGameState s) => m ()

问题出在HasPlayerState的实例定义中。我只能在列表中选择一个元素。如何使用列表元素管理这种嵌套状态?

修改 我意识到我可以使用Currentplayer字段作为索引。但现在我似乎遇到了ix

的问题
data PlayerState = PlayerState {
  _playerState_Cash :: Int
                               }
data GameState = GameState {
  _gameState_CurrentPlayer :: Int,
  _gameState_PlayerStates  :: [PlayerState]
                           }

makeClassy ''PlayerState
makeClassy ''GameState

instance HasPlayerState GameState where
  playerState = gameState_PlayerStates
  playerState_Cash = playerState . ix gameState_CurrentPlayer . playerState_Cash

有错误:

 • Could not deduce (Applicative f) arising from a use of ‘ix’
      from the context: Functor f
        bound by the type signature for:
                   playerState :: Lens' GameState PlayerState

0 个答案:

没有答案