I tried to implement a general sliding window algorithm in a list of items. A common use case is to find the largest number in all windows of length 5. Or it can calculate how many elements in the window are true for some predicate.
A sliding window that runs from left to right and supports some data structure. The element goes beyond the window; it calls removein the data structure. if a new element falls into the window, we addelement in the data structure. It also has a function aggregatethat calculates something in the data structure.
The naive data structure to be used is dequeue, but it is potentially possible that someone would want to use a different data structure for special use cases.
My initial idea was to have a long function that looks like this:
runSlidingWindow :: (c->(Int,a)->c) -- add
-> (c->(Int,a)->c) -- remove
-> (c->b) -- aggregate
-> c -- identity
-> Int -- width
-> [(Int,a)] -- input
-> [(Int,b)]
But I was wondering if there is any Haskell method, so we can define some class Window a b cso that we can rewrite the function as
runSlidingWindow :: (Window a b c=>WindowInstance a b c)
-> WindowInstance a b c
-> [(Int,a)]
-> [(Int,b)]
runSlidingWindow window input
Of course, I do not think this is the correct Haskell code. We want to force any type that is an instance Window a b cto have functions of the form
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
It is important to have a type class Window a b c, as this allows others to implement their own sliding windows.
I do not know how this can be done in Haskell. I think using a family of type classes is possible? I would like to see an example.