私自身の興味のために、単純な FRP バックエンドを実装しようとしています。
純粋な関数を使用することにしました。そのため、コアに IO はありません。実装は信号変換器に基づいています。
私はすでに2つの方法を試しました:
newtype SF a b = SF { listen :: [a] -> [b] }
https://gist.github.com/Heimdell/9675964#file-streamer-hs-L1
と
newtype SF a b = SF { run :: a -> (b, SF a b) }
https://gist.github.com/Heimdell/9675964#file-behaviour-hs-L1 (名前が間違っています、ごめんなさい)
fold/integrate :: (a -> b -> b) -> b -> SF a b
どちらの方法でも、信号統合用のコンビネータを作成できます。
どちらの方法にも問題があります。有効な ArrowApply/Monad インスタンスを作成することは不可能のようです。
ストリームの方法:ペアのリストがあります。
(arrow, x)
つまり、unzip
リストのペアです(arrows, xs)
。map head
それらの結果を望むならzipWith ($)
、キャリー・アロング・アロー・ミューテーションを失います。head arrows
listenを作成するxs
と、最初に取られた矢印の状態がフリーズします。
明示的なステートウェイ:
instance ArrowApply Behaviour where app = Behaviour $ \(bf, a) -> let (bf1, c) = bf `runBehaviour` a in (app, c)
ここで、return にどうにか有効に注入する必要がありますが
bf1
、app
これは不可能です (実際に by を注入すると(const bf1 *** id)
、他の実装の 2 番目のものと同様の無効な動作が生成されます。
SF
ArrowApply インスタンスを許可する方法はありますか?
PS: ブランチが長期間使用されていない場合、ストリームウェイの ArrowChoice でメモリ リークが発生します。今のところ、それを修正することはできません。漏れのないバージョンを作成することは可能ですか?
PPS: 時間が必要な場合は、入力で圧縮できます。