merge

The merge operator combines a left and right stream concurrently.

This is a reference guide to merge. It describes:

Basic behaviour

The merge operator combines a left input stream and right input stream to produce a resulting stream. It pulls on both left and right streams concurrently.

The following examples merge two streams of characters.

Experiment with different delays for ab.

Note how decreasing the delay makes the a and b elements appear earlier in the output, while increasing it makes them appear later. The actual output order is non-deterministic.

Unlike sequential methods of combination, merge pulls on both its input streams when it is pulled on. This can be seen in the example for all non-zero delays. When merge is first pulled on, it pulls on both ab and xy concurrently.

Termination

The resulting stream of merge terminates when the last input stream is done.

The operators mergeHaltBoth, mergeHaltL and mergeHaltR have different terminaton behaviours.

Termination on either input with mergeHaltBoth

The resulting stream of mergeHaltBoth terminates when either input stream is done.

The following example combines ab and xy with mergeHaltBoth. Experiment with different delays for ab. Note that if ab is done first, no more elements are pulled from xy and the resulting stream terminates. Conversely, if xy is done first, no more elements are pulled from ab.

Note that when ab emits all elements immediately (the seconds between ab elements is 0), the xy stream is not run at all. The ab stream is done before the xy stream is pulled on.

Termination on the left with mergeHaltL

The resulting stream of mergeHaltL terminates when the left input stream is done.

The following example combines ab and xy with mergeHaltL. Experiment with different delays for ab. Note that the resulting stream always terminates when ab is done.

The last element of the stream is not guaranteed to be an output of the left stream. If an element is outputted by the right stream concurrently to the termination of the left stream, it may be outputted as the last element.

Termination on the right with mergeHaltR

The resulting stream of mergeHaltR terminates when the right input stream is done.

The following example combines ab and xy with mergeHaltR. Experiment with different delays for ab. Note that the resulting stream always terminates when xy is done.

As with mergeHaltL, the last element of the stream is not guaranteed to be an output of the right stream. If an element is outputted by the left stream concurrently to the termination of the right stream, it may be outputted as the last element.

Exit cases on termination

Exit cases on mergeHalt operators

An input stream that is terminated due to the completion of another input stream has an exit case of Canceled.

This can be observed with onFinalizeCase.

The following example shows the exit cases of both input streams when merged with mergeHaltBoth.

Experiment with varying the delay of ab. Note that if the ab stream is done first, the xy stream has an exit case of Canceled. Conversely, if the xy stream is done, the ab stream has an exit case of Canceled.

Exit cases on resulting stream termination

If a fixed number of elements are requested from the resulting stream, it may terminate before the input streams are done. The input streams are canceled.

The following example shows the exit cases when a single element is pulled from the resulting stream. Both ab and xy are canceled.

Exit cases on error

If an error is raised in an input stream, the other input stream is terminated with an exit case of Canceled.

In this example, the ab stream raises an error when it is pulled on for the second time.

If the xy stream is stopped due to an error raised by the ab stream, its exit case is Canceled.

Error propagation

Errors in the left or right input stream are propagated to the resulting stream.

In the following example, the ab stream raises an error when it is pulled on for the second time. The error is propagated to the resulting stream, causing the entire program to terminate with the error.

Experiment with the delay before the error.

Resource management

The left or right streams may have finalizers associated with them. These finalizers are executed when their associated stream terminates.

In thid example, finalizers are associated with the ab and xy streams.

Experiment with different delays for ab. Note that the ab finalizer is executed when the ab stream is done, not when the resulting stream is done. Similarly, the xy finalizer is executed when the xy stream is done.

Resource management on error

If an error is raised in either the left or right stream, the finalizers are run.

In this example, the ab stream raises an error when it is pulled for the second time. As before, finalizers are associated with the ab and xy streams.

Experiment with the delay before the error. Notice that the ab and xy finalizers are always run, provided that their respective streams are pulled on.

Note that when ab raises an error immediately (the delay before the error is 0), the xy finalizer is not run. The error is raised before the xy stream is pulled on.