Search code examples
streamfunctional-programmingreactive-cocoafrp

FRP: How to multiply the number of events in one stream


The question is quite simple, but I can not come up with a good solution.

Let's say I have a stream. The stream can send only 4 events: A, B, C, D

It can be represented like:

[--A--A----C---B--D--...]

Consider now, that each event has its encoded value. For example:

A -> 1, 0, 0, 0
B -> 0, 1, 0, 0
...

Now, the question is: How can I transform this stream, using encoded values of A,B,C,D events, that each event would be represented as 4 events instead.

To make everything clear, this is what i want:

The stream I have:

[--A--A----C---B--D--...]

I know that:

A -> 1, 0, 0, 0
B -> 0, 1, 0, 0
...

The stream I want to make:

[--1-0-0-0--1-0-0-0----0-0-1-0---0-1-0-0--0-0-0-1--...]

One solution I can come up with is to Map the stream, returning substream for each event, and then flatten the result. But I'm not sure how it should be implemented in terms of the FRP.

If I should use combination of streams, please provide a relevant example. I use Reactive-Cocoa personally, but you can answer using any other language, it just doesn't matter.


Solution

  • I found the solution which works for me. My guess about flattening streams was pretty reasonable. So here is how I achieved the desired result:

    // first producer is SignalProducer<String, NoError>
    // which posts events "A", "B", "C", "D"
    
        let secondProducer = firstProducer.flatMap(.Latest, transform: { value -> SignalProducer<Bool, NoError> in
    
            let result:[Bool] = ["A" == value, "B" == value,  "C" == value, "D" == value]
            return SignalProducer<Bool, NoError>(values: result)
        })
    
        secondProducer.startWithNext({value in
            print("value : \(value)")
        })
    

    The main point here is: I use flatMap to transform first signal producer into the second, which encodes each of A, B, C and D into 4 signals of Bool.

    It is the basics of Frp, but I hope some of the beginners can find it useful.