Реалізуймо базові операції здатності Stream.
У функціональних мовах такі функції, як filter, map і reduce, трапляються дуже часто. Реалізуймо серію базових функціональних комбінаторів для здатності потоку, не використовуючи наявних функцій. Для цього нам доведеться написати власні обробники здатностей.
💡 Ми назвемо цю здатність MyStream, щоб уникнути конфлікту з наявною здатністю Stream у стандартній бібліотеці.
Операції, які нам потрібно реалізувати:
MyStream.fromList (отримавши масив елементів, створити потік елементів)MyStream.toList (отримавши потік елементів, матеріалізувати його в масив)MyStream.toListWithResult (отримавши потік елементів, матеріалізувати його в масив разом із результатом функції потоку)MyStream.ignore (отримавши потік елементів, знехтувати випущеними значеннями й повернути результати функції потоку)MyStream.filter (отримавши предикат і MyStream, повернути MyStream усіх елементів, для яких predicate(item) є правдою);MyStream.map (отримавши функцію і MyStream, повернути MyStream результатів застосування function(item) до всіх елементів);MyStream.flatMap (отримавши функцію, яка породжує MyStream, і MyStream, повернути MyStream результатів застосування function(item) до всіх елементів)Stream
Stream - це здатність Unison, яку використовують, щоб випромінювати значення.
Ми можемо використати здатність Stream, якщо маємо функцію, яка має видавати значення як побічний ефект під час її виклику. Наприклад, ця функція повертає останнє значення масиву, але випромінює поточний підсумок у міру перегляду кожного елемента:
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 як List разом із поверненим значенням функції, яка його продукує, за допомогою обробника здатності:
> Stream.toListWithResult! emitRunningTotal
⧩
([1, 3, 5, 7, 9], 5)