このような質問は私の前の質問と同じです:State and IO Monadsモナドトランススタックをメインからキックスタートする方法は?
私の目標は、ファイル用の簡単なテキストエディタを作成することです。私は既にEditor
コンポーネントを持っています。このコンポーネントは、基礎となるデータ構造上のすべての編集アクションを素早くカプセル化します。
type Session = StateT AppState (StateT Editor IO)
AppState
は、アプリケーション(現在開いているファイルのグローバルな状態を保持している:私は今、素敵なモナド変圧器スタックを持っているように、私の前の質問への回答に
おかげで、私は私のプログラムをリファクタリングすることができました、etc. ...)、Editor
は、アプリケーションの編集コンポーネントの内部状態を表します(キャレットは、など)。私は実際に私のmain
関数から私の変圧器スタックを、キックスタートできるかわからないが、今、これまでのところは良い
eventLoop :: Session()
:私は、アプリケーションのメインドライバである機能を持っていますか?メインは私のスタックの根底にあるIO
モナドに何かを返さなければなりません。
main = do
let initialAppState = ...
return $ runStateT eventLoop initialAppState
しかし、私は今、私のEditor
を初期化します。ここで私の推測では、私は私のAppState
を初期化する必要があり、その後のような何かをするということですか?
data AppState = { editor :: Editor , ... }
が、今それがAppState
の外に移動したと変圧器スタック上の兄弟の多少になる:
私を混乱主なものは、リファクタリングの前に、Editor
は単にAppState
のメンバーであったということです。 Editor
はまだAppState
に属していてはなりません。
Session
をAppState
とEditor
の両方で正しく初期化してから、main
から実行しますか?
'StateT'の中に' StateT'をラップするには、正しい状態にアクセスするためのリフトの厄介な組み合わせが必要です。 'StateSt(AppState、EditorState)'(または独自のデータ型)を使うのが良いでしょう。そうすれば、MonadStateの 'get'などを持ち上げなくても使うことができます。 –