州Monads:交换另一种模式?

时间:2010-08-05 02:42:19

标签: haskell abstraction monads boilerplate state-monad

所以我正在Haskell中编写一个游戏,并且我将玩家视为一系列与各种转弯阶段相关的状态改变函数。最初,这看起来像:

let game'  = phase1 game
    game'' = phase2 game'
-- etc.

国家monadosity的候选人,对吗?这导致更优雅:

do
  phase1
  phase2
-- etc.

然而,似乎我必须更改phase1phase2等等,以一个样板“状态获取”步骤开始:

phase1 = get >>= \game -> -- ...

我希望有一种方法可以解决这个问题,所以我可以避免调用者和被调用者都使用样板文件。我太新了,不知道这是什么方式(这是我的第一个真正的Haskell项目)。有什么建议吗?

1 个答案:

答案 0 :(得分:8)

嗯,它还不是很符合monadosic。这是Endo幺半群的主要候选者。这导致更优雅

game = mconcat [ phase1, phase2, ... ]

每个阶段都写着:

phase1 = Endo $ \game -> ...

如果您需要在每个阶段中返回一些额外数据以及新状态,您将转移到monad。在这种情况下,一个简单的函数将使您的样板更容易忍受:

phase :: (GameState -> GameMonad a) -> GameMonad a
phase f = f =<< get

然后编写一个阶段:

phase1 = phase $ \game -> do ...

但是如果你想使用这个状态,你可能不得不给它一个名字(除非你可以通过使用getsdata-accessor来确定自由点),并且如果你不能比函数和lambda得到更多的话。