首页 文章

国家Monad的传播

提问于
浏览
3

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

所以我可以返回一个元组(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 回答

  • 4

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

    请注意 runState 封装了有状态计算,因此如果你有两个并排的 runState 计算,它们会赢得't see each other'个状态(除非你将结果从一个传递给另一个 . )这也应该给你一个提示"up" runState 需要 .

相关问题