国家单子的传播 [英] Propagation of State Monad
问题描述
我具有以下功能,可以在游戏世界的图形"的边缘"周围走动.它改变了世界状况-尤其是玩家的位置.我需要报告一条消息,提醒玩家他们的位置也发生了变化.
I have the following function for walking around "edges" of the "graph" of my game world. It alters the state of the world--specifically, the player's location. I need to report a message alerting the player of their change in location as well.
所以我可以返回(message,newWorld)的元组,也可以使用State monad. (对吗?我是新手.)
So I could either return a tuple of (message, newWorld), or I could use a State monad. (Right? I'm new to this stuff.)
这是我尝试单子方法的尝试:
Here's my attempt at the monad approach:
walk dir = do
world <- get
let attempt = filter (\e -> edgeDirection e == dir) $ edges
edges = (worldEdges world) M.! playerLoc
playerLoc = playerLocation $ worldPlayer world
case attempt of
[] -> return "You can't go that way."
(edge : _) -> do
put world'
return message
where world' = world { worldPlayer = player' }
player' = (worldPlayer world) { playerLocation = loc }
loc = edgeLocation edge
message = "You go " ++ (downcase $ show dir)
问题是,现在调用 walk
的函数有一个State monad要处理.我是在这里runState
还是我也有使用State monads的功能,像这样:
The thing is, now the function that calls walk
has a State monad to deal with. Do I runState
it right there, or do I have that function use State monads too, like this:
parseWalk dir =
let direction = case dir of
('e' : _) -> Just East
('n' : _) -> Just North
('s' : _) -> Just South
('w' : _) -> Just West
('u' : _) -> Just Up
('d' : _) -> Just Down
_ -> Nothing
in case direction of
Just d -> walk d
Nothing -> return "You can't go that way"
那parseWalk
的呼叫者又如何呢?我是否应该尝试让这个State monad尽可能长时间地通过?我应该在类型签名中看到很多MonadState ...
吗?
Then what about parseWalk
's caller, and so forth? Should I try to keep this State monad passed around as long as possible? Should I be seeing a lot of MonadState ...
in my type signatures?
推荐答案
这是一种思考方式:runState
需要初始状态作为其参数.您的代码中该初始状态在哪里可用?那就是状态monad需要传播的距离.
Here's one way of thinking about it: runState
requires an initial state as its parameter. Where is this initial state available in your code? That's how far the state monad needs to propagate.
请注意,runState
封装了有状态计算,因此,如果您有两个并排的runState
计算,它们将不会看到彼此的状态(除非您将结果从一个传递到另一个).这也应该给您提示runState
需要向上"的距离.
Note that runState
encapsulates the stateful computation, so that if you have two runState
computations side-by-side, they won't see each other's states (unless you pass the result from one to the other.) This also should give you a hint how far "up" the runState
needs to be.
这篇关于国家单子的传播的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!