Haskell 哈斯克尔提早退出州政府(守卫?)
我有一个代表我的应用程序的游戏状态的类型,对于这个问题,假设它很简单,如:Haskell 哈斯克尔提早退出州政府(守卫?),haskell,monads,monad-transformers,alternative-functor,Haskell,Monads,Monad Transformers,Alternative Functor,我有一个代表我的应用程序的游戏状态的类型,对于这个问题,假设它很简单,如: Game { points :: Int } 我用状态单子定义游戏逻辑 type GameState a = StateT Game a addPoints :: Int -> GameState () addPoints num = do Game p <- get put $ Game (p+num) 如果它击中了防护装置,我希望它离开状态,而不在块中执行任何其他操作 我怎么做?对于
Game { points :: Int }
我用状态单子定义游戏逻辑
type GameState a = StateT Game a
addPoints :: Int -> GameState ()
addPoints num = do
Game p <- get
put $ Game (p+num)
如果它击中了防护装置,我希望它离开状态,而不在块中执行任何其他操作
我怎么做?对于MonadPlus来说,这似乎几乎是可能的,但我不确定是否可以使用mzero来表示“返回您在您的状态中已经拥有的内容”。谢谢 导入
Control.Monad.Trans.Maybe
并在StateT
上使用。然后,您可以使用中止计算,或者如Kevin Ballard所说,条件
如果条件
为假
,则停止计算;您所要做的就是将每个块括在runMaybeT
中。(请注意,您必须提升StateT
monad上定义的每个选项,或者更改它们的类型以使用任何具有所需状态的monad,如操作::(MonadState m Game)=>…
)
请注意,您可能有transformers
包,其中包含Control.Monad.Trans.Maybe
,即使您没有直接使用它;mtl
包包含标准的monad模块,如Control.monad.State
,依赖于它。我想我是在充实猪倌对这个问题的评论
ensure :: GameState Bool -> GameState () -> GameState ()
ensure p k = do
t <- p
when t k
addPoints num = do
ensure (evenResult num) $ do
...
sure::GameState Bool->GameState()->GameState()
确保pk=do
tStateT
已经是一个MonadPlus
。你试过仅仅使用Control.Monad.guard
吗?@KevinBallard:StateT s m
如果m
是,那么它只是一个MonadPlus
;实例只是将mzero
和mplus
提升一级。Control.Monad.when是你的人?诚然,当需要一个Bool
值时,是一个麻烦,而不是一个计算出Bool
。但罗马不是一天烧成的。如果您的test
位于m Bool
,您可以编写(test>=)。当$action
时进行翻转,这是一个相当复杂的问题。或者,我可以将sure写成sure::(Game->Bool)->GameState()->GameState()
,我的所有谓词函数都写成where::Game->Bool
,而不是where::GameState Bool
addPoints num = do
guard evenResult
...
-- or this
addPoints num = do
guardIsEvenResult
...
ensure :: GameState Bool -> GameState () -> GameState ()
ensure p k = do
t <- p
when t k
addPoints num = do
ensure (evenResult num) $ do
...