背景:我正在创建一个有状态的游戏,用于读取和写入游戏的全局状态。
我想把我的游戏分成一些组件,比如“字符”,为这些组件提供一种与全局状态交互的特定域方式。理想情况下,这可能是定义我可以使用的表单MonadState Character m => m a的特定操作,但每个这样的m a都会对父级(全局状态)进行更改。
我已经搜索过在状态单元之间的转换,或者提供了一个从一个状态单元到另一个状态单元的接口,但是这方面的具体语言超出了我的知识范围。我也已经在使用镜片了,我想知道我是否能用它们做点什么。
编辑
我想做一些像moveCharacter :: MonadState Character m => Int -> Int -> m ()这样的事情
让它在里面执行move :: MonadState World m => Int -> Int -> m ()。基本上,把世界的细节从角色中抽离出来。
谢谢!
发布于 2015-10-26 00:57:11
听起来像是在寻找Zoom,它允许您将镜头视图上的有状态操作转换为镜头源上的有状态操作。
发布于 2015-10-27 11:40:34
您实际上需要两个转换函数:一个从世界中提取字符,另一个用修改后的字符修改世界。你可以这样把它们放在一起:
extractCharacter :: World -> Character
extractCharacter = error "Tried to call placeholder function"
replaceCharacter :: World -> Character -> World
replaceCharacter = error "Tried to call placeholder function"
runCharacterSubroutine :: (Functor m) =>
StateT Character m a -> StateT World m a
runCharacterSubroutine act = StateT $ \w ->
fmap (\(a,c') -> (a,replaceCharacter w c')) $
runStateT act (extractCharacter w)在您的游戏中,您可能需要一些更复杂的东西,但这只是在extractCharacter和replaceCharacter中添加一个额外的参数的问题。
请注意,我给出的函数只有在StateT位于monad转换器堆栈的顶部时才能工作。如果不是:您必须使用mmorph包
https://stackoverflow.com/questions/33336722
复制相似问题