這是我之前的一個後續問題:State and IO Monads如何從main啓動monad變壓器堆棧?
我的目標是爲文件創建一個簡單的文本編輯器。我已經有了一個Editor
組件,它很好地封裝了底層數據結構上的所有編輯操作。
多虧了答案,我剛纔的問題,我可以修改我的程序,所以,我現在有一個很好的單子轉換堆棧:
type Session = StateT AppState (StateT Editor IO)
AppState
包含應用程序(當前打開的文件的全局狀態等等),而Editor
代表應用程序編輯組件的內部狀態(插入符號位於...等)。我有一個功能是應用程序的主要驅動力:
eventLoop :: Session()
到目前爲止好,但現在我不知道我其實可以從我main
功能腳踏啓動我的變壓器棧? Main必須在我的堆棧的底部返回IO
monad中的內容。我的猜測是,我必須初始化我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)'(或者你自己的數據類型)會更好,所以你可以使用'MonadState'''''等。 –