传播国家Monad [英] Propogation of State Monad

查看:106
本文介绍了传播国家Monad的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

所以我可以返回一个(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
个案尝试
[] - >回报你不能这样。
(edge:_) - >做
把世界'
返回信息
where world'= world {worldPlayer = player'}
player'=(worldPlayer world){playerLocation = loc}
loc = edgeLocation edge
message =You go++(downcase $ show dir)

事情是,现在调用的函数 walk 有一个状态monad需要处理。



<$ p $

parseWalk dir =
let direction = case bir
('e':_) - > Just East
('n':_) - >正北
('s':_) - >南部
('w':_) - > Just West
('u':_) - >刚刚涨
('d':_) - >只是下降
_ - >没有
的情况下方向
只需d - > walk d
Nothing - >返回你不能这样做

那么 parseWalk 的调用者,等等?我应该尽量保持这个国家monad尽可能长时间传递?我应该在我的类型签名中看到很多 MonadState ... 吗?



此致



在美国加州困惑


解决方案

下面是考虑这个问题的一种方式: runState 需要初始状态作为其参数。代码中的初始状态在哪里可用?这就是状态monad需要传播的程度。



请注意, runState 封装了有状态计算,所以如果你有两个 runState 计算并排,他们不会看到对方的状态(除非你将结果从一个传递给另一个)。这也应该给你一个提示 runState 需要多少up。


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.

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)

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"

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?

Sincerely,

Confused in California

解决方案

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.

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.

这篇关于传播国家Monad的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆