所以我正在Haskell中编写一个游戏,并且我将玩家视为一系列与各种转弯阶段相关的状态改变函数。最初,这看起来像:
let game' = phase1 game
game'' = phase2 game'
-- etc.
国家monadosity的候选人,对吗?这导致更优雅:
do
phase1
phase2
-- etc.
然而,似乎我必须更改phase1
,phase2
等等,以一个样板“状态获取”步骤开始:
phase1 = get >>= \game -> -- ...
我希望有一种方法可以解决这个问题,所以我可以避免调用者和被调用者都使用样板文件。我太新了,不知道这是什么方式(这是我的第一个真正的Haskell项目)。有什么建议吗?
答案 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 ...
但是如果你想使用这个状态,你可能不得不给它一个名字(除非你可以通过使用gets或data-accessor来确定自由点),并且如果你不能比函数和lambda得到更多的话。