国家Monad的传播

时间:2011-03-22 00:31:02

标签: haskell state monads

我有以下功能可以绕过我游戏世界“图形”的“边缘”。它改变了世界的状态 - 特别是玩家的位置。我需要报告一条消息,提醒玩家他们的位置变化。

所以我可以返回(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 个答案:

答案 0 :(得分:4)

这是思考它的一种方式:runState需要初始状态作为其参数。您的代码中的初始状态在哪里?这就是状态monad需要传播的距离。

请注意runState封装了有状态计算,因此如果你并排进行两次runState次计算,他们就不会看到彼此的状态(除非你将结果从一个传递给另一个。)这也应该给你一个暗示runState需要多远的提示。