Streamというabilityの基本的な操作を実装します。
関数型言語では、filterやmap、reduceのような関数がよく使われます。ここでは、既存の関数を使わずに、ストリームのabilityのための基本的な関数型コンビネーターを一通り実装します。そのためには、abilityのハンドラーを自分で書く必要があります。
💡 標準ライブラリにある既存のStreamabilityと衝突しないように、ここではこのabilityをMyStreamと呼ぶことにします。
実装する必要がある操作は次のとおりです。
MyStream.fromList(要素のリストを受け取り、要素のストリームを作ります)MyStream.toList(要素のストリームを受け取り、それをリストとして具体化します)MyStream.toListWithResult(要素のストリームを受け取り、ストリーム関数の結果とあわせてリストとして具体化します)MyStream.ignore(要素のストリームを受け取り、発行された値を無視して、ストリーム関数の結果を返します)MyStream.filter(述語とMyStreamを受け取り、predicate(item)が真になるすべての要素からなるMyStreamを返します)MyStream.map(関数とMyStreamを受け取り、すべての要素にfunction(item)を適用した結果のMyStreamを返します)MyStream.flatMap(MyStreamを生成する関数とMyStreamを受け取り、すべての要素にfunction(item)を適用した結果のMyStreamを返します)StreamアビリティについてStreamは、値を発行するために使うUnisonのアビリティです。
呼び出されている間に、副次的な効果として値を生成する関数があるなら、Streamアビリティを使うことになるでしょう。たとえば、次の関数は配列の最後の値を返しますが、要素を1つ見るたびにそれまでの合計を発行します。
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]
アビリティハンドラーを使えば、Streamを生成する関数の戻り値と一緒に、そのStreamをListとして実体化できます。
> Stream.toListWithResult! emitRunningTotal
⧩
([1, 3, 5, 7, 9], 5)