私の毎週のレンズの質問の時間;ズームモナドスタックのコンテキスト
私はモナドスタックを持っている:
newtype Action a = Action
{ runAct :: StateT ActionState (ReaderT Hooks IO) a
} deriving (Functor, Applicative, Monad, MonadState ActionState, MonadReader Hooks, MonadIO)
data ActionState = ActionState
{ _ed :: Editor
, _asyncs :: [AsyncAction]
}
私は私のエディタレンズが依存HasEditor
型クラスを生成するEditor
タイプにmakeClassy
を使用。
Editor
には、多くの場合、Buffer
があります。私は、特定のバッファ(BufAction
)上で動作するアクションのための別のモナドスタックタイプを定義しました。唯一の違いは、StateTがBuffer
の上にあるということである:私は特定のバッファにStateTをズームするzoom (editor.buffers.ix selected)
を使用BufAction
を実行するために
newtype BufAction a = BufAction
{ runBufAct::StateT Buffer (ReaderT Hooks IO) a
} deriving (Functor, Applicative, Monad, MonadState Buffer, MonadReader Hooks, MonadIO)
。問題は、現在BufAction
の中にeditor
以上のレンズを使用したり、HasEditor
を必要とするレンズを使用できなくなったことです。
Action
はすべて、BufAction
の内部で実行され、BufAction
はAction
の内部で実行できません。この場合、BufAction
には完全なActionState
が必要ですが、実行するには特定のバッファへの参照も必要です。 Action
にはActionState
が必要です。したがって、BufAction
はより限定的なモナドであり、Action
を埋め込み可能にする必要があります。
だから、約私はこのようなタイプのいくつかの並べ替えたい:GHCはこれにチョークしかし
newtype Action a = forall s. HasEditor s => Action
{ runAct :: StateT s (ReaderT Hooks IO) a
} deriving (Functor, Applicative, Monad, MonadState s, MonadReader Hooks, MonadIO)
を。 newtypeに存在と制約を処理することはできません。
data
タイプに切り替えました。しかし、私はGeneralizedNewtypeDerivingを失い、手動で 節を派生させるすべてを実装する必要があります。私は本当にやっていないだろう。
また、タイプエイリアスを試しました。これは私がtypeclassesを派生する必要はありませんが、私はエラーを他のデータ型にも埋め込んでいるため、エラーが発生します。私はここにAction
を使用するので、たとえば:異なるタクトを取る
• Illegal polymorphic type: Action()
GHC doesn't yet support impredicative polymorphism
• In the definition of data constructor ‘ActionState’
In the data type declaration for ‘ActionState’
;:
data ActionState = ActionState
{ _ed :: Editor
, _asyncs :: [Async (Action())]
, _hooks :: Hooks
, _nextHook :: Int
}
私はに実行します私も柔軟MonadStateインスタンスを実行しようとしました:
instance (HasEditor s, HasBuffer s) => (MonadState s) BufAction where
が、取得:
• Illegal instance declaration for ‘MonadState s BufAction’
The coverage condition fails in class ‘MonadState’
for functional dependency: ‘m -> s’
Reason: lhs type ‘BufAction’ does not determine rhs type ‘s’
Un-determined variable: s
• In the instance declaration for ‘(MonadState s) BufAction’
をMonadStateが機能の依存関係を使用しているので...
本当にこの1に貼り付け、私は使用することができますハンド!
ありがとうございました!私は本当に助けに感謝します!
質問の種類が不明です。 「BufAction」の状態が「Action」よりも小さい場合、どのように動作するのでしょうか?の状態?確かにそれは他の方法ラウンドする必要がありますか? –
申し訳ありませんが、それは不明です。私は少し詳しく説明しようとします。 BufActionは 'Action'よりも小さい状態を使用しますが、 'より多くの情報'を持つ状態であるため、それほど「小さな状態」ではありません。 'BufAction'が'(ActionState、BufId) 'として利用できる状態を考えることができます。本質的に 'ActionState'全体が(' Action'と同じように)利用可能ですが、特定のバッファにも焦点を合わせることができる情報があります。したがって、 'ActionState'で動作する' Action'は 'BufAction'でも利用できるはずです。 'BufAction'は' BufId'コンテキストを必要とし、 'Action'では実行できません。任意の明確な? –
これはもちろん、BufActionが実際に大きな状態を含むものに変更する必要があります。それはHasEditorとHasBufferという制約が参照するものです。 'Action'は' HasEditor'だけの状態で実行されます。 'BufAction'は' HasEditor'と 'HasBuffer'で状態を超えて実行する必要がありますので、より制限的です。 –