-
Notifications
You must be signed in to change notification settings - Fork 6
/
ReactiveUtils.hs
58 lines (48 loc) · 1.69 KB
/
ReactiveUtils.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{-# LANGUAGE ExistentialQuantification
, ScopedTypeVariables
, MultiParamTypeClasses
, FlexibleInstances
, TypeFamilies
#-}
-----------------------------------------------------------------------------
-- |
-- Module : ReactiveUtils
-- Copyright : (c) 2012 Andreas-C. Bernstein
-- License : BSD-style (see LICENSE)
-- Maintainer : andreas.bernstein@gmail.com
--
-- Reactive banana utilities. Most of them very similar to the ones from
-- the Reactive library.
--
-----------------------------------------------------------------------------
module ReactiveUtils
(
integral
, sumB
, withPrevE
, withPrevEWith
, diffE
, unique
, once
) where
import Reactive.Banana
import Data.VectorSpace
import Data.AffineSpace
import Data.Active (fromDuration, Time)
integral :: (VectorSpace v, Scalar v ~ Double) => Event t Time -> Behavior t v -> Behavior t v
integral t b = sumB $ (\v dt -> fromDuration dt *^ v) <$> b <@> diffE t
sumB :: AdditiveGroup a => Event t a -> Behavior t a
sumB = accumB zeroV . fmap (^+^)
withPrevE :: Event t a -> Event t (a,a)
withPrevE = withPrevEWith (,)
withPrevEWith :: (a -> a -> b) -> Event t a -> Event t b
withPrevEWith f e = filterJust . fst . mapAccum Nothing $ g <$> e
where
g y Nothing = (Nothing , Just y)
g y (Just x) = (Just (f y x), Just y)
diffE :: AffineSpace a => Event t a -> Event t (Diff a)
diffE = withPrevEWith (.-.)
unique :: Eq a => Event t a -> Event t a
unique = filterJust . accumE Nothing . fmap (\a acc -> if Just a == acc then Nothing else Just a)
once :: Event t a -> Event t a
once e = whenE (True `stepper` (False <$ e)) e