module FRP.Helm.Signal(
Signal(..),
constant,
combine,
lift,
lift2,
lift3,
(<~),
(~~),
foldp,
count,
countIf,
lift4,
lift5,
lift6,
lift7,
lift8
) where
import Control.Applicative
import Data.Traversable (sequenceA)
import FRP.Elerea.Param hiding (Signal)
import qualified FRP.Elerea.Param as Elerea (Signal)
import FRP.Helm.Sample
import FRP.Helm.Engine
newtype Signal a = Signal {signalGen :: SignalGen Engine (Elerea.Signal (Sample a))}
instance Functor Signal where
fmap = liftA
instance Applicative Signal where
pure = Signal . pure . pure . pure
(Signal f) <*> (Signal x) = Signal $ liftA2 (liftA2 (<*>)) f x
constant :: a -> Signal a
constant x = Signal $ stateful (Changed x) (\_ _ -> Unchanged x)
combine :: [Signal a] -> Signal [a]
combine = sequenceA
lift :: (a -> b) -> Signal a -> Signal b
lift = fmap
lift2 :: (a -> b -> c) -> Signal a -> Signal b -> Signal c
lift2 f a b = f <~ a ~~ b
lift3 :: (a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
lift3 f a b c = f <~ a ~~ b ~~ c
lift4 :: (a -> b -> c -> d -> e) -> Signal a -> Signal b -> Signal c -> Signal d
-> Signal e
lift4 f a b c d = f <~ a ~~ b ~~ c ~~ d
lift5 :: (a -> b -> c -> d -> e -> f) -> Signal a -> Signal b -> Signal c -> Signal d
-> Signal e -> Signal f
lift5 f a b c d e = f <~ a ~~ b ~~ c ~~ d ~~ e
lift6 :: (a -> b -> c -> d -> e -> f -> g) -> Signal a -> Signal b -> Signal c -> Signal d
-> Signal e -> Signal f -> Signal g
lift6 f a b c d e f1 = f <~ a ~~ b ~~ c ~~ d ~~ e ~~ f1
lift7 :: (a -> b -> c -> d -> e -> f -> g -> h) -> Signal a -> Signal b -> Signal c -> Signal d
-> Signal e -> Signal f -> Signal g -> Signal h
lift7 f a b c d e f1 g = f <~ a ~~ b ~~ c ~~ d ~~ e ~~ f1 ~~ g
lift8 :: (a -> b -> c -> d -> e -> f -> g -> h -> i) -> Signal a -> Signal b -> Signal c -> Signal d
-> Signal e -> Signal f -> Signal g -> Signal h
-> Signal i
lift8 f a b c d e f1 g h = f <~ a ~~ b ~~ c ~~ d ~~ e ~~ f1 ~~ g ~~ h
(<~) :: (a -> b) -> Signal a -> Signal b
(<~) = lift
infixl 4 <~
(~~) :: Signal (a -> b) -> Signal a -> Signal b
(~~) = (<*>)
infixl 4 ~~
foldp :: (a -> b -> b) -> b -> Signal a -> Signal b
foldp f ini (Signal gen) =
Signal $ gen >>= transfer (pure ini) update_
>>= delay (Changed ini)
where update_ _ (Unchanged _) y = Unchanged (value y)
update_ _ (Changed x) y = Changed $ f x (value y)
count :: Signal a -> Signal Int
count = foldp (\_ y -> y + 1) 0
countIf :: (a -> Bool) -> Signal a -> Signal Int
countIf f = foldp (\v c -> c + fromEnum (f v)) 0