Предположим, у меня что-то вроде этого:
data Environment = ...
data MyState = ...
data Report = ...
updateState :: Environment -> MyState -> MyState
updateState = ...
report :: MyState -> Report
report = ...
foo :: ReaderT Environment (State MyState) Report
foo = do env <- ask
state <- lift get
let newState = updateState env state
lift $ put newState
return $ report newState
Что у меня в голове - это моделирование процесса времени, в котором у меня есть параметры, которые будут сохранены в Environment
, динамическое состояние будет сохранено вMyState
и информация, которую я хочу собирать на каждом шаге симуляции, будет храниться в Report
.
Теперь я не хочу выполнять много шагов симуляции и получать список с отчетамиза каждый шаг по времени.
Я обычно делал это без ReaderT
и использовал для передачи таких параметров:
foo :: Enviroment -> State MyState Report
Тогда я бы просто сделал:
manySteps :: Int -> Enviroment -> State MyState [Report]
manySteps n env = replicate n $ (foo env)
I 'я путаюсь с типами lift
и replicateM
.Есть ли комбинация, которая повторяла бы монаду State MyState
внутри трансформатора?
В будущем я заменим ReaderT Environment (State MyState) Report
на ReaderT Environment (StateT MyState (Rand StdGen)) Report
, так что лучше все сделать правильно, прежде чем использовать этот тип монстра :(.
edit: в качестве дополнительного вопроса - есть ли лучшая стратегия, чем использование ReaderT Environment (State MyState) Report
?