Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I unify two or more Signals in elerea?

Is there something like reactive-bananas union function in elerea?

union :: Signal a -> Signal a -> Signal a

This just merges the two signals into one stream. Ideally I am searching for an efficient union of a large number (14k) of signals:

unions :: [Signal a] -> Signal a

There doesn't seem to be anything in the docs, nor is there anything that I could recognize as a building block therefor.


Edit: except for maybe this:

unionSignal :: a -> Signal a -> Signal a -> SignalGen p (Signal a)
unionSignal initial a b = do
  (s,f) <- execute $ external initial
  _ <- effectful1 f a
  _ <- effectful1 f b
  return s

But ... that is just ugly and doesn't capture the idea of union.

like image 507
fho Avatar asked Sep 29 '14 16:09

fho


1 Answers

There's nothing quite like union for elerea's signal because of how an elerea network is modeled. An elerea signal contains exactly one value at each step, so there's no sensible way to combine arbitrary values at the same time. However, there are a few different ways you could combine signals, depending on how the values should be combined.

unions :: [Signal a] -> Signal [a]
unions = sequence    -- or Data.Traversable.sequenceA

or you can fold directly over the inputs

foldS :: (a -> b -> b) -> b -> [Signal a] -> Signal b
foldS f b signals = foldr (\signal acc -> f <$> signal <*> acc) (return b) signals
-- I think a right fold is more efficient, but it depends on elerea's internals and I'm not sure

If you don't actually care about the value and just want to make sure the signal gets switched in, you can use

unions_ :: [Signal a] -> Signal ()
unions_ = sequence_
like image 158
John L Avatar answered Sep 17 '22 22:09

John L