「適切に」netwire 5に動的なワイヤセットを実装しようとしています。私はワイヤーのワイヤーの質問への回答を読みましたが、例のコードが動作に変換されて、の1回の実行でEvent
空でないことを示す方法に依存する方法が特に好きではありません.stepWire
Event
したがって、 s を介して動的セットにワイヤを追加および削除したいと考えていUnsafe.Event
ます。Wire
簡単にするために削除部分を削除し、 sを追加できるようにしましょう。
dynWireSet1 :: (Monad m, Monoid s)
=> Wire s e m (a, Event (Wire s e m a b)) [b]
各イベントは、内部に隠されているワイヤーの (最初は空の) リスト (または他のセット) に新しいワイヤーを追加し、それらはすべて実行され、すべて type の入力を取得し、a
それらの出力をリストに収集します。
実行部分は比較的簡単で、グーグルで検索できる例があります。
dynWireSet1 = runWires1 []
runWires1 :: (Monad m, Monoid s)
=> [Wire s e m a b]
-> Wire s e m (a, Event (Wire s e m a b)) [b]
runWires1 wires = mkGen $ \session (input, event) -> do
stepped <- mapM (\w -> stepWire w session (Right input)) wires
let (outputs, newwires) = unzip stepped
return (sequence outputs, runWires1 newwires)
上記の例はイベントを無視します。event
関数 from以外では、遷移関数内でイベントを使用することは不可能であると思われUnsafe.Event
ます。あれは正しいですか?避けたいUnsafe.Event
。
一歩下がって、推奨されているイベントの使用方法を確認すると、非常に有望な関数が表示されます。
krSwitch :: Monad m
=> Wire s e m a b
-> Wire s e m (a, Event (Wire s e m a b -> Wire s e m a b)) b
さて、単純化された runWires から始めるとどうなるでしょうか:
runWires2 :: (Monad m, Monoid s)
=> [Wire s e m a b]
-> Wire s e m a [b]
runWires2 wires = mkGen $ \session input -> do
stepped <- mapM (\w -> stepWire w session (Right input)) wires
let (outputs, newwires) = unzip stepped
return (sequence outputs, runWires2 newwires)
dynWireSet を krSwitch にします。
dynWireSet2 :: (Monad m, Monoid s)
=> Wire s e m (a, Event (Wire s e m a b)) [b]
dynWireSet2 = krSwitch (runWires2 []) . second (mkSF_ (fmap addWire))
addWire :: Wire s e m a b -> Wire s e m a [b] -> Wire s e m a [b]
addWire = undefined
私はほとんどそこにいます!ここで、新しいワイヤーをに挿入するfmap
だけでよければ、準備は完了です。しかし、これは一般的なケースでは不可能です。実際、私が正しく理解すれば、出力のすぐ上にあります。使い物にならない。(:)
runWires2
newwires
fmap
WGen
fmaps
そして今、ここに私の考えがあります。の新しいバリアントを紹介しましょう。内部状態を異なるデータ型で保持するため、data Wire
暫定的に呼び出します。WCarry g st
その遷移関数はタイプになります
((a, c) -> m (b, c))
そして、初期状態が与えられると、コンストラクターは次のような Wire を生成します。
mkCarry :: Monad m => ((a, c) -> m (b, c)) -> c -> Wire s e m a b
mkCarry transfun state = mkGenN $ \input -> do
(output, newstate) <- transfun (input, state)
return (Right output, mkCarry transfun newstate)
結果のワイヤーにWCarry
タイプの代わりにタイプを導入するだけです。の観点WGen
から再定式化するのは簡単です。runWires
mkCarry
次に、fmap インスタンスは次のようになります。
fmap f (WCarry g st) = WCarry g (fmap f st)
これにより、「hidden inside」状態オブジェクトが変更さkrSwitch
れ、この種の s で function を有意義に使用Wire
して、以前の値を失うことなく内部状態を微調整できるようになります。
これは理にかなっていますか?私がやろうとしていることがより簡単な方法で可能であれば、アドバイスをお願いします! 私が話していることが理にかなっている場合、どうすればそれを行うことができますか? WCarry を使用して定義をローカルに拡張し、data Wire
対応する定義を持つ興味深い Class インスタンスを拡張して追加することは可能ですか? 他にアドバイスはありますか?
ありがとう。