代码之家  ›  专栏  ›  技术社区  ›  J Cooper

国家单子:用一种模式换另一种模式?

  •  4
  • J Cooper  · 技术社区  · 14 年前

    所以我用haskell写了一个游戏,我把玩家的回合表达为一系列的状态改变函数,这些函数与不同的回合相关联。最初,这看起来像:

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

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

    do
      phase1
      phase2
    -- etc.
    

    不过,那我就得换衣服了 phase1 , phase2 ,等人从样板“状态获取”步骤开始:

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

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

    1 回复  |  直到 13 年前
        1
  •  8
  •   luqui    14 年前

    嗯,还不完全是单原子的。这是 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更简洁的函数。