Chciałbym wprowadzić pewien rodzaj dławienia wydarzeń w reaktywnym bananie. Powinien działać tak, aby zdarzenie nie zostało przepuszczone, jeśli dotrze do mniej niż sekund opóźnienia od ostatniego zdarzenia, które przeszło. Jeśli nie jest przepuszczony, to jest przechowywany i jest uruchamiany po delcie sekund od ostatniego wystrzelonego zdarzenia.Impulsy z dławiącym reaktywnym bananem
Poniżej znajduje się program, który implementuje to w przypadku list numerów oznaczonych stemplem czasu. Czy można to przetłumaczyć na reaktywny banan?
Ponadto, w przypadku bananów reaktywnych, w jaki sposób mogę wystrzelić wydarzenie w ciągu x sekund po jakimś innym wydarzeniu?
module Main where import Data.List -- 1 second throtling -- logic is to never output a value before 1 second has passed since last value was outputed. main :: IO() main = print $ test [ (0.0, 1.0), (1.1, 2.0), (1.5,3.0), (1.7,4.0), (2.2, 5.0) ] --should output [ (0.0, 1.0), (1.1, 2.0), (2.1,4.0), (3.1, 5.0) ] test :: [(Double,Double)] -> [(Double,Double)] test list = g v (concat xs) where (v, xs) = mapAccumL f (-50,Nothing) list g (t, Just x) ys = ys ++ [ (t+1,x) ] g _ ys = ys f (lasttime, Just holdvalue) (t,x) = if t > (lasttime+1) then if t > (lasttime + 2) then ((t, Nothing), [ (lasttime+1,holdvalue), (t,x)]) else ((lasttime+1, Just x) , [ (lasttime+1,holdvalue) ]) else ((lasttime, Just x), []) f (lasttime, Nothing) (t,x) = if t > (lasttime+1) then ((t,Nothing) , [ (t, x) ]) else ((lasttime, Just x), [])
Jeśli nie jesteś zadowolony z IO, możesz wdrożyć timer jako coś, co nasłuchuje zdarzenia zawierającego komunikaty ("start", "stop", "reset") i zwraca inne zdarzenie. Ogólnie, polecam umieścić funkcje, które używają 'reactate' do monady' NetworkDescription', np. 'Throttle :: ... -> NetworkDescription t (Event ta)' zamiast 'throttle :: .. -> (Event ta, NetworkDescription t()) '. –
Ok, to czyni go znacznie czystszym, a pod względem składni nie różni się zbytnio od posiadania przepustnicy :: Event t a -> Int -> Event t a (po prostu użyj <- zamiast let in the do statement). Ponownie zaimplementowałem Twoją sugestię: https://gist.github.com/2905841. Myślę, że jestem całkiem zadowolony z tego rozwiązania. –