import { IOptional, Mapper, Optional } from '@emprespresso/pengueno'; export interface ICons extends Iterable { readonly value: T; readonly next: IOptional>; readonly replace: Mapper>; readonly before: Mapper>, ICons>; } export class Cons implements ICons { constructor( public readonly value: T, public readonly next: IOptional> = Optional.none(), ) {} public before(head: IOptional>): ICons { return new Cons(this.value, head); } public replace(_value: T): ICons { return new Cons(_value, this.next); } *[Symbol.iterator]() { for (let cur = Optional.some>(this); cur.present(); cur = cur.flatMap((cur) => cur.next)) { yield cur.get().value; } } static addOnto(items: Iterable, tail: IOptional>): IOptional> { return Array.from(items) .reverse() .reduce((cons, value) => Optional.from>(new Cons(value, cons)), tail); } static from(items: Iterable): IOptional> { return Cons.addOnto(items, Optional.none()); } }