游戏编程中MTL风格Classy Lens状态管理实现技术问询
MTL风格下用Classy Lens管理动态玩家列表的GameState困惑
我正在用Haskell开发一款游戏,采用全局GameState来管理整体状态,其中包含一个动态可变数量的PlayerState列表。目前我写出的核心代码如下:
{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE FlexibleInstances #-} import Control.Lens data PlayerState = PlayerState { _playerState_Id :: Int , _playerState_Cash :: Int } deriving (Show, Eq) data GameState = GameState { _gameState_CurrentPlayer :: Int , _gameState_PlayerStates :: [PlayerState] } deriving (Show, Eq) makeClassy ''PlayerState makeClassy ''GameState instance HasPlayerState GameState where playerState_Id = gameState_PlayerStates . ix 0 . playerState_Id playerState_Cash = gameState_PlayerStates . ix 0 . playerState_Cash
我意识到当前的HasPlayerState GameState实现存在明显问题:我硬编码用ix 0直接取第一个玩家,但游戏里玩家数量是动态变化的,而且GameState里明明维护了_gameState_CurrentPlayer来标记当前操作的玩家。这显然不是合理的设计,所以想请教大家几个关于MTL风格Classy Lens状态管理的技术问题:
- 怎么正确实现
HasPlayerState GameState实例,让它能自动关联到GameState中标记的当前玩家,而不是固定索引的玩家? - 面对动态变化的玩家列表,怎么避免使用
ix可能带来的索引越界风险?有没有更安全的Lens用法? - 在MTL模式下,针对这种包含动态元素集合的状态,设计Lens的最佳实践是什么?
内容的提问来源于stack exchange,提问作者McBear Holden
相关产品推荐
相关产品推荐

