Haskell ReaderT设计模式与MTL StateT模式

时间:2019-03-11 21:25:36

标签: haskell

我正在设计一个基本上使用StateT并只是更新状态的小型游戏。下面是简化版:

{-# LANGUAGE TemplateHaskell #-}

import           Control.Lens
import           Control.Monad
import           Control.Monad.IO.Class
import           Control.Monad.State
import           Control.Monad.State.Class
import           System.Random

data PlayerState = PlayerState {
  _psName  :: String,
  _psScore :: Int
                               } deriving (Show)

makeClassy ''PlayerState

data Game = Game {
  _turns   :: Int,
  _players :: [PlayerState]
                 } deriving (Show)

makeClassy ''Game

randomGameInit :: IO Game
randomGameInit = do
  players <- replicateM 5 $  PlayerState <$> (replicateM 4 $ randomRIO ('a', 'z')) <*> randomRIO (1,10)
  return $ Game 0 players

update :: (MonadState s m, HasGame s) => m ()
update = do
  players . ix 0 . psName %= (\_ -> "mordor")
  turns %= (+1)
  exitCondition <- fmap (>10) (turns <%= id)
  unless exitCondition update

main :: IO ()
main = do
  init <- randomGameInit
  runStateT update init >> print "Game Over"

我最近了解了ReaderT Design Pattern vs mtl StateT,它鼓励在StateT的{​​{1}}内部用可变引用替换ReaderT

我想知道如何使用ReaderT修改代码。最具体地说,许多IO函数的类型为:Lens,显然需要在一个国家内部。这是否意味着(MonadState s m)库函数是为StateT设计的,而不是为ReaderT设计的?如何将LensLens设计模式一起使用?

0 个答案:

没有答案