4

所以我正在用 Haskell 编写一个游戏,我将玩家的回合表达为一系列与不同回合阶段相关的状态改变函数。最初,这看起来像:

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

国家单一性的主要候选人,对吧?这导致更优雅:

do
  phase1
  phase2
-- etc.

但是,似乎我必须更改phase1, phase2, et al 以从样板“状态获取”步骤开始:

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

我希望有一种方法可以将其抽象出来,这样我就可以避免调用者和被调用者的样板文件。我太新了,不知道这种方式是什么(这是我的第一个真正的 Haskell 项目)。有什么建议吗?

4

1 回答 1

8

好吧,它还不是很单调。这是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来解决pointfreeness ),在这种情况下,你不能得到比这更简洁的了一个函数和一个 lambda。

于 2010-08-05T03:05:56.907 回答