【发布时间】:2011-03-22 00:31:02
【问题描述】:
我有以下功能可以在我的游戏世界的“图形”的“边缘”周围走动。它改变了世界的状态——特别是玩家的位置。我还需要报告一条消息,提醒玩家他们的位置发生了变化。
所以我可以返回一个 (message, newWorld) 元组,也可以使用 State monad。 (对吧?我是新手。)
这是我对 monad 方法的尝试:
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 monad,像这样:
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 ... 吗?
【问题讨论】:
-
由于您正在遍历和修改大型数据结构,您可能希望使用 Zipper。