4

私自身の興味のために、単純な 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 arrowslistenを作成するxsと、最初に取られた矢印の状態がフリーズします。
  • 明示的なステートウェイ:

    instance ArrowApply Behaviour where
        app =
            Behaviour $ \(bf, a) ->
                let (bf1, c) = bf `runBehaviour` a
    
                in (app, c)
    

    ここで、return にどうにか有効に注入する必要がありますがbf1appこれは不可能です (実際に by を注入すると(const bf1 *** id)、他の実装の 2 番目のものと同様の無効な動作が生成されます。

SFArrowApply インスタンスを許可する方法はありますか?

PS: ブランチが長期間使用されていない場合、ストリームウェイの ArrowChoice でメモリ リークが発生します。今のところ、それを修正することはできません。漏れのないバージョンを作成することは可能ですか?

PPS: 時間が必要な場合は、入力で圧縮できます。

4

1 に答える 1