такого рода вопрос к моему предыдущему: State and IO MonadsКак сбрасывать блок трансформатора монады из основного?
Моя цель - создать простой текстовый редактор для файлов. У меня уже есть компонент Editor
, который прекрасно инкапсулирует все действия по редактированию в базовой структуре данных.
Благодаря ответы на мой предыдущий вопрос, я был в состоянии реорганизовать свою программу, так что теперь у меня есть хороший стек монады трансформатора:
type Session = StateT AppState (StateT Editor IO)
AppState
держит глобальное состояние приложения (в настоящее время открытого файла , и т. д.), а Editor
- это внутреннее состояние редактирующего компонента приложения (где находится каретка и т. д.). У меня есть функция, которая является основным драйвером приложения:
eventLoop :: Session()
До сих пор так хорошо, однако сейчас я не знаю, как я могу на самом деле ножной стартер моего стек трансформатора от моей main
функции? Главная должна вернуть что-то в монаде IO
, которая находится в самой базе моего стека. Я думаю, что я должен инициализировать моей AppState
, а затем сделать что-то вроде:
main = do
let initialAppState = ...
return $ runStateT eventLoop initialAppState
Но где я инициализировать мой Editor
сейчас?
Главное заблуждение меня является то, что перед рефакторинга, Editor
был просто членом AppState
:
data AppState = { editor :: Editor , ... }
, но теперь она переместилась из AppState
и стал своего родного брата в стеке трансформатора. Должно ли Editor
быть частью AppState
, потому что его изменение означает изменение общего состояния?
Как правильно инициализировать мой Session
как с AppState
и Editor
, а затем запустить его из моей main
?
Для обхода 'StateT' внутри' StateT' потребуется неудобная комбинация лифтов для доступа к правильному состоянию. Лучше было бы использовать только «StateT (AppState, EditorState)» (или собственный тип данных), чтобы вы могли использовать 'get' и такие как' get' MonadState, и без подъема. –