Предположим, у меня есть что-то вроде этого:
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)
Я путаюсь с типами lift
и replicateM
. Есть ли комбинация, которая воспроизвела бы монаду State MyState
внутри трансформатора?
В будущем я заменю ReaderT Environment (State MyState) Report
на ReaderT Environment (StateT MyState (Rand StdGen)) Report
, так что лучше все сделать правильно, прежде чем иметь этот тип монстра :(.
редактировать: как побочный вопрос - есть ли лучшая стратегия, чем использование ReaderT Environment (State MyState) Report
?