Created
August 30, 2021 17:57
-
-
Save baetheus/9bfa19654200ee68dad5c4d8238444e5 to your computer and use it in GitHub Desktop.
Playing with Iterable/AsyncIterable
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import type * as HKT from "./hkt.ts"; | |
| import type * as TC from "./type_classes.ts"; | |
| import { createDo } from "./derivations.ts"; | |
| import { createSequenceStruct, createSequenceTuple } from "./sequence.ts"; | |
| /******************************************************************************* | |
| * Kind Registration | |
| ******************************************************************************/ | |
| export const URI = "Iterable"; | |
| export type URI = typeof URI; | |
| declare module "./hkt.ts" { | |
| // deno-lint-ignore no-explicit-any | |
| export interface Kinds<_ extends any[]> { | |
| [URI]: Iterable<_[0]>; | |
| } | |
| } | |
| /******************************************************************************* | |
| * Functions | |
| ******************************************************************************/ | |
| const isIterator = <A>( | |
| o: (() => Iterator<A>) | Generator<A>, | |
| ): o is Generator<A> => Object.hasOwn(o, Symbol.iterator); | |
| export function make<A>( | |
| fa: (() => Iterator<A>) | Generator<A>, | |
| ): Iterable<A> { | |
| if (isIterator(fa)) { | |
| return fa; | |
| } | |
| return { [Symbol.iterator]: fa }; | |
| } | |
| export function of<A>(...a: A[]): Iterable<A> { | |
| return make(function* () { | |
| let index = -1; | |
| const length = a.length; | |
| while (++index < length) { | |
| yield a[index]; | |
| } | |
| }); | |
| } | |
| export function ap<A, I>( | |
| tfai: Iterable<(a: A) => I>, | |
| ): (ta: Iterable<A>) => Iterable<I> { | |
| return (ta) => | |
| make(function* () { | |
| for (const fai of tfai) { | |
| for (const a of ta) { | |
| yield fai(a); | |
| } | |
| } | |
| }); | |
| } | |
| export function map<A, I>(fai: (a: A) => I): (ta: Iterable<A>) => Iterable<I> { | |
| return (ta) => | |
| make(function* () { | |
| for (const a of ta) { | |
| yield fai(a); | |
| } | |
| }); | |
| } | |
| export function join<A>(tta: Iterable<Iterable<A>>): Iterable<A> { | |
| return make(function* () { | |
| for (const ta of tta) { | |
| for (const a of ta) { | |
| yield a; | |
| } | |
| } | |
| }); | |
| } | |
| export function chain<A, I>( | |
| fati: (a: A) => Iterable<I>, | |
| ): (ta: Iterable<A>) => Iterable<I> { | |
| return (ta) => | |
| make(function* () { | |
| for (const a of ta) { | |
| for (const i of fati(a)) { | |
| yield i; | |
| } | |
| } | |
| }); | |
| } | |
| /******************************************************************************* | |
| * Modules | |
| ******************************************************************************/ | |
| export const Functor: TC.Functor<URI> = { map }; | |
| export const Apply: TC.Apply<URI> = { ap, map }; | |
| export const Applicative: TC.Applicative<URI> = { of, ap, map }; | |
| export const Chain: TC.Chain<URI> = { ap, map, chain }; | |
| export const Monad: TC.Monad<URI> = { of, ap, map, join, chain }; | |
| /******************************************************************************* | |
| * Derived Functions | |
| ******************************************************************************/ | |
| export const { Do, bind, bindTo } = createDo(Monad); | |
| export const sequenceTuple = createSequenceTuple(Apply); | |
| export const sequenceStruct = createSequenceStruct(Apply); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment