Tracks
/
Unison
/
Exercises
/
Stream Ops

Stream Ops

Medium

Instructions

Implement basic `Stream` ability operations.

In functional languages, functions like `filter`, `map`, and `reduce` are very common. Implement a series of basic functional combinators for a stream ability without using existing functions. You'll need to write your own ability handlers for this.

💡 We're going to call this ability `MyStream` to avoid conflicting with the existing `Stream` ability in the standard library.

The operations you'll need to implement are:

• `MyStream.fromList` (given a list of elements, create a stream of elements )
• `MyStream.toList` (given a stream of elements, materialize it to a list)
• `MyStream.toListWithResult` (given a stream of elements, materialize it to a list alongside the result of the stream function)
• `MyStream.ignore` (given a stream of elements, ignore the emitted values, returning the results of the stream function)
• `MyStream.filter` (given a predicate and a `MyStream`, return the `MyStream` of all items for which `predicate(item)` is true);
• `MyStream.map` (given a function and a `MyStream`, return the `MyStream` of the results of applying `function(item)` on all items);
• `MyStream.flatMap` (given a function which produces a `MyStream` and a `MyStream`, return the `MyStream` of the results of applying `function(item)` on all items)

A `Stream` is a Unison ability that is used to emit values.

You might use the `Stream` ability if you have a function which should produce values as a secondary effect while it is being called. For example, this function returns the last value of the list, but emits a running total as each element is seen:

``````emitRunningTotal : '{Stream Nat} Nat
emitRunningTotal = 'let
use Nat +
List.foldLeft (
acc a -> let
runningTotal = acc + a
Stream.emit runningTotal
a
) 0 [1,2,3,4,5]
``````

We can materialize the Stream as a List alongside the return value of the function which produces it with an ability handler:

``````> Stream.toListWithResult! emitRunningTotal
⧩
([1, 3, 5, 7, 9], 5)
``````
Last updated 29 March 2023
Edit via GitHub