我有以下功能可以绕过我游戏世界“图形”的“边缘” . 它改变了世界的状态 - 特别是玩家的位置 . 我需要报告一条消息,提醒玩家他们的位置变化 .
所以我可以返回一个元组(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 monads,如下所示:
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
的来电怎么样?等等?我应该尽量让这个州的monad继续传递吗?我的类型签名中是否应该看到很多 MonadState ...
?
1 回答
这是思考它的一种方式:
runState
需要一个初始状态作为其参数 . 您的代码中的初始状态在哪里?这是状态monad需要传播的距离 .请注意
runState
封装了有状态计算,因此如果你有两个并排的runState
计算,它们会赢得't see each other'个状态(除非你将结果从一个传递给另一个 . )这也应该给你一个提示"up"runState
需要 .