要素のリストに一般的なスライディング ウィンドウ アルゴリズムを実装しようとしていました。一般的な使用例は、長さ 5 のすべてのウィンドウで最大数を見つけることです。または、ウィンドウ内のいくつかの述語に対して true である要素の数をカウントできます。
左から右に移動するスライディング ウィンドウで、一部のデータ構造を維持します。remove
要素が、データ構造で呼び出すウィンドウの外に出ます。新しい要素がウィンドウ内にある場合、add
その要素をデータ構造に追加します。aggregate
また、データ構造で何かを計算する関数もあります。
使用する単純なデータ構造はデキューですが、特別なユースケースのために他の種類のデータ構造を使用したい人がいる可能性があります。
私の最初のアイデアは、このような長い関数を持つことでした
runSlidingWindow :: (c->(Int,a)->c) -- add
-> (c->(Int,a)->c) -- remove
-> (c->b) -- aggregate
-> c -- identity
-> Int -- width
-> [(Int,a)] -- input
-> [(Int,b)]
しかしWindow a b c
、関数を
runSlidingWindow :: (Window a b c=>WindowInstance a b c)
-> WindowInstance a b c
-> [(Int,a)]
-> [(Int,b)]
runSlidingWindow window input
もちろん、上記は有効な Haskell コードではないと思います。Window a b c
のインスタンスであるすべての型に、次の形式の関数を持つように強制したい
add :: (Window a b c=>WindowInstance a b c)
-> WindowInstance a b c
-> a
-> WindowInstance a b c
remove :: (Window a b c=>WindowInstance a b c)
-> WindowInstance a b c
-> a
-> WindowInstance a b c
aggregate :: (Window a b c=>WindowInstance a b c)
-> WindowInstance a b c
-> b
したがって、この型クラスを持つことWindow a b c
は重要です。これにより、他のユーザーが独自のスライディング ウィンドウを実装できるようになるからです。
Haskellでこれを行う方法がわかりません。タイプクラスファミリーを使用すると、これは可能だと思いますか? 例を見てみたい。