【问题标题】:Is it correct to use the Reader monad in this turn-based game?在这个回合制游戏中使用 Reader monad 是否正确?
【发布时间】:2015-06-27 15:15:04
【问题描述】:

我需要学习使用 Reader monad。 (还有作家和国家)。

我所做的游戏竞赛总是包含在整个游戏中有效的全局参数。还有一堆只在一个回合内有效的参数。

我结束了所有最新的比赛,其中有很多功能,几乎都以 Game 和 Turn 作为输入参数。

在阅读了 reader monad 之后,我正在考虑:

data Game = Game AllNeeded StrategicPositions AndGameRelatedStuffs
data Turn = Turn PlayersPositions AndTurnDependentStuffs 

并且对于每个循环,当我收到轮流相关数据时,我计划有一个变量Reader Game Turn

turnReader = Reader currentGame currentTurn
let actionToPerform = play turnReader

你认为这是 Reader monad 应用的好例子吗? 您认为我可以/应该蒙上眼睛并在这种情况下学习使用 Reader monad 吗?还是有更合适的单子,比如 State ?

【问题讨论】:

  • 这不是基于意见的,因为 (a) Reader monad 具有非常精确的语义,并且 (b) 与标题相比,实际问题的范围有限。我将编辑标题以使其更清晰。

标签: haskell monads


【解决方案1】:

Reader monad 在您想要在计算中读取的 不可变 状态时使用。基本上就像有一个额外的参数隐式传递给所有的单子动作。

在您的游戏中,您似乎确实想要改变某些东西(即回合或游戏状态)。在这种情况下,State monad 可能更容易使用。

为了使用Reader,你必须对依赖于状态的所有动作进行分组,在 monad 中执行它们,然后 在 monad 之外改变状态并使用修改后的运行新的 monadic 计算状态等。这听起来很麻烦。

请注意,使用Reader 实际上类似于使用State。简单地说:put 操作(和衍生产品)是不允许的。因此,您可以使用Reader 开始写作,如果您遇到想要修改状态的地方,您知道使用State 可能会更好。 反之亦然:从使用 State 开始,如果您最终从不修改状态,请将其替换为 Reader

【讨论】:

    【解决方案2】:

    假设Turn 的值每回合都在变化,而Game 没有变化,拥有StateT Turn (ReaderT Game IO) 之类的东西似乎是合理的。您需要为此阅读 monad 转换器(我个人喜欢 "Monad Transformers Step by Step" (PDF))。

    【讨论】:

      猜你喜欢
      • 2014-01-20
      • 1970-01-01
      • 2017-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多