Designing a general slide window program in Haskell, need type class family? -
i trying implement general sliding window algorithm on list of elements. common use case find largest number in windows of length 5. or can count how many elements in window true predicate.
the sliding window going left right, , maintain data structure. element fall outside window calls remove
on data structure. if new element falls within window, add
element data structure. has function aggregate
, compute on data structure.
the naive data structure use dequeue, it's potentially possible want use other kind of data structure special use cases.
my original idea have long function looks 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 wondering there haskell way can define class window b c
, such can rewrite function
runslidingwindow :: (window b c=>windowinstance b c) -> windowinstance b c -> [(int,a)] -> [(int,b)] runslidingwindow window input
of course don't think above valid haskell code. want force type instance of window b c
have functions of form
add :: (window b c=>windowinstance b c) -> windowinstance b c -> -> windowinstance b c remove :: (window b c=>windowinstance b c) -> windowinstance b c -> -> windowinstance b c aggregate :: (window b c=>windowinstance b c) -> windowinstance b c -> b
so having type class window b c
important, since allows others implement own sliding windows.
i'm not aware of how can done in haskell. think using type class family possible? see example.
whenever think “i need typeclass”, stop, , consider whether record of functions do.
data window b c = window { add :: c -> (int, a) -> c, remove :: c -> (int, a) -> c, aggregate :: c -> b, identity :: c, width :: int} runslidingwindow :: window b c -> [(int, a)] -> [(int, b)]
or even, hiding implementation type:
{-# language existentialquantification #-} data window b = forall c. window { add :: c -> (int, a) -> c, remove :: c -> (int, a) -> c, aggregate :: c -> b, identity :: c, width :: int} runslidingwindow :: window b -> [(int, a)] -> [(int, b)]
Comments
Post a Comment