【发布时间】:2016-08-12 09:27:41
【问题描述】:
这是我上一个问题的后续问题:State and IO Monads
我的目标是为文件创建一个简单的文本编辑器。我已经有一个Editor 组件,它很好地封装了底层数据结构上的所有编辑操作。
感谢我之前的问题的答案,我能够重构我的程序,以便我现在拥有一个不错的 monad 转换器堆栈:
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 的一部分,因为修改它意味着修改整体状态?
如何使用AppState 和Editor 正确初始化我的Session,然后从我的main 运行它?
【问题讨论】:
-
将
StateT包裹在StateT内将需要笨拙的电梯组合才能访问正确的状态。 imo 最好只使用StateT (AppState, EditorState)(或您自己的数据类型),这样您就可以使用MonadState的get等而无需提升。
标签: haskell monads monad-transformers state-monad