我正在嘗試在netwire 5「正確地」執行一組動態導線。 我已閱讀wires of wires問題的答案,我不特別喜歡該示例中的代碼如何依靠Event
轉換爲在上顯示非空的行爲,恰好一個執行的stepWire
。Haskell Netwire:正確完成電線的導線
因此,我想要通過Event
s在動態設置中添加和刪除導線,並且希望不會攻擊Unsafe.Event
或同等hackery。讓我們放棄對簡單去除一部分,只是使它可以添加Wire
S:
dynWireSet1 :: (Monad m, Monoid s)
=> Wire s e m (a, Event (Wire s e m a b)) [b]
每個事件增加了一個新的導線電線隱藏在內部的(初始爲空)列表(或其他組),他們全部運行,全部獲得類型爲a
的輸入,並將其輸出收集到列表中。
的運行部分是比較容易的,具有googleable實例,例如:以上
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)
實施例忽略事件。我懷疑 不可能使用轉換函數中的事件,而不是 函數使用Unsafe.Event
。那是對的嗎? I 想避開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
我快到了!現在,如果我只能通過a (:)
而不是runWires2
並將新電線插入newwires
,那麼我將全部設置!但在一般情況下,這是不可能的。其實,fmap
超過WGen
只是fmaps
以上的輸出,如果我說得對。無用。
現在,這是我的想法。我們來介紹一個data Wire
的新變體,我暫時將其稱爲WCarry g st
,因爲它將以不同的數據類型傳送其內部狀態。它的轉移函數將是給定的初始狀態下的類型
((a, c) -> m (b, c))
和,的,構造會產生線是這樣的:
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
類型到所得絲。根據mkCarry
很容易重寫runWires
。
然後,FMAP實例將是這個樣子:
fmap f (WCarry g st) = WCarry g (fmap f st)
它將改變「隱藏在」狀態對象,我們就可以使用krSwitch
功能有意義的這種Wire
S,調整他們的內部狀態而不會失去先前的價值。
這是否有意義?如果我想要以更簡單的方式進行操作,請諮詢!如果我說的是有道理的話,我怎麼去解決呢?是可以在本地擴展data Wire
定義與WCarry,並擴展添加有趣的類實例與相應的定義?任何其他建議?
謝謝。
它適用於組合現有設置和新線的輸出。但在下一步中,我顯然希望從集合中刪除導線(例如使用地圖來表示)。我可以按照您的建議刪除不需要的輸出,但不會導致內存泄漏? – crosser
評論自己的評論,也許使用懶惰的地圖會緩解內存泄漏問題?會嗎? – crosser
當您想要移除'w'時,您可以讓'w &&& ws'響應一個切換回'ws'的事件。 – Mokosha