(() => { // src/mixin.js var _appliedMixin = "__mixwith_appliedMixin"; var apply = (superclass, mixin) => { let application = mixin(superclass); application.prototype[_appliedMixin] = unwrap(mixin); return application; }; var isApplicationOf = (proto, mixin) => proto.hasOwnProperty(_appliedMixin) && proto[_appliedMixin] === unwrap(mixin); var hasMixin = (o, mixin) => { while (o != null) { if (isApplicationOf(o, mixin)) return true; o = Object.getPrototypeOf(o); } return false; }; var _wrappedMixin = "__mixwith_wrappedMixin"; var wrap = (mixin, wrapper) => { Object.setPrototypeOf(wrapper, mixin); if (!mixin[_wrappedMixin]) { mixin[_wrappedMixin] = mixin; } return wrapper; }; var unwrap = (wrapper) => wrapper[_wrappedMixin] || wrapper; var _cachedApplications = "__mixwith_cachedApplications"; var Cached = (mixin) => wrap(mixin, (superclass) => { let cachedApplications = superclass[_cachedApplications]; if (!cachedApplications) { cachedApplications = superclass[_cachedApplications] = /* @__PURE__ */ new Map(); } let application = cachedApplications.get(mixin); if (!application) { application = mixin(superclass); cachedApplications.set(mixin, application); } return application; }); var DeDupe = (mixin) => wrap(mixin, (superclass) => hasMixin(superclass.prototype, mixin) ? superclass : mixin(superclass)); var BareMixin = (mixin) => wrap(mixin, (s) => apply(s, mixin)); var Mixin = (mixin) => DeDupe(Cached(BareMixin(mixin))); var mix = (superclass) => new MixinBuilder(superclass); var MixinBuilder = class { constructor(superclass) { this.superclass = superclass || class { }; } /** * Applies `mixins` in order to the superclass given to `mix()`. * * @param {Array.} mixins * @return {FunctionConstructor} a subclass of `superclass` with `mixins` applied */ with(...mixins) { return mixins.reduce((c, m) => m(c), this.superclass); } }; // src/algebra/interfaces.js var ProtectedConstructor = Symbol("ProtectedConstructor"); var NotImplementedError = class extends Error { /** @param {string} name */ constructor(name) { super(`${name} is not implemented`); } }; var MethodType = Object.freeze({ Instance: 0, Static: 1 }); var Method = class _Method { #name; /** @type {MethodType} */ #type = MethodType.Instance; /** @type {Fn} */ #implementation; /** * @param {string | Method} name */ constructor(name) { if (name instanceof _Method) { return name; } this.#name = name; } /** * @param {string | Method} value */ static from(value) { return new _Method(value); } isInstance() { this.#type = MethodType.Instance; return this; } isStatic() { this.#type = MethodType.Static; return this; } /** @param {Fn} f */ implementation(f) { this.#implementation = f; return this; } /** * @param {string} interfaceName */ _defaultImplementation(interfaceName) { const err2 = new NotImplementedError( `${interfaceName}::${this.#name}` ); return function() { throw err2; }; } /** * @param {Function} target */ _getInstallationPoint(target) { switch (this.#type) { case 0: return Object.getPrototypeOf(target); case 1: return target; default: return target; } } /** * @param {Interface} builder * @param {Function} target */ implement(builder, target) { const impl = this.#implementation || this._defaultImplementation(builder.name); this._getInstallationPoint(target)[this.#name] = impl; } }; var Implementations = Symbol(); var Interface = class { #name; /** @type {MixinFunction} */ #mixin; /** @type {Set} */ #methods = /* @__PURE__ */ new Set(); /** @type {Set} */ #interfaces = /* @__PURE__ */ new Set(); /** @param {string} name */ constructor(name) { this.#name = name; this.#mixin = Mixin(this.build.bind(this)); } get name() { return this.#name; } findInterfaces(type) { let interfaces = /* @__PURE__ */ new Set(); let current = type; while (current != null) { interfaces = new Set(current[Implementations]).union(interfaces); current = Object.getPrototypeOf(current); } return interfaces; } /** * @param {{ name: string }} type * @returns {boolean} */ implementedBy(type) { return this.findInterfaces(type).has(this); } /** * @param {...(PropertyKey | Method)} methods * @returns {this} */ specifies(...methods) { this.#methods = new Set( methods.map(Method.from).concat(...this.#methods) ); return this; } /** * @param {...Interface} interfaces * @returns {this} */ extends(...interfaces) { this.#interfaces = new Set(interfaces.concat(...this.#interfaces)); return this; } /** * @returns {MixinFunction} */ asMixin() { return this.#mixin; } /** * @param {FunctionConstructor} base */ build(base) { const interfaces = [...this.#interfaces.values()]; const mixins = interfaces.map((x) => x.asMixin()); const Interfaces5 = mix(base).with(...mixins); const Algebra2 = class extends Interfaces5 { }; for (const method of this.#methods) { method.implement(this, Algebra2); } const prototype = Object.getPrototypeOf(Algebra2); prototype[Implementations] = new Set(interfaces); return Algebra2; } }; var BaseSet = class { }; var AlgebraWithBase = (base) => (...algebras) => { return mix(base).with(...algebras.map((x) => x.asMixin())); }; var Algebra = AlgebraWithBase(BaseSet); var Setoid = new Interface("Setoid").specifies("equals"); var Ord = new Interface("Ord").specifies("lte"); var Semigroupoid = new Interface("Semigroupoid").specifies("compose"); var Category = new Interface("Category").extends(Semigroupoid).specifies( Method.from("id").isStatic() ); var Semigroup = new Interface("Semigroup").specifies("concat"); var Monoid = new Interface("Monoid").extends(Semigroup).specifies( Method.from("empty").isStatic() ); var Group = new Interface("Group").extends(Monoid).specifies("invert"); var Filterable = new Interface("Filterable").specifies("filter"); var Functor = new Interface("Functor").specifies("map"); var Contravariant = new Interface("Contravariant").specifies("contramap"); var Apply = new Interface("Apply").extends(Functor).specifies("ap"); var Applicative = new Interface("Applicative").extends(Apply).specifies( Method.from("of").isStatic() ); var Alt = new Interface("Alt").extends(Functor).specifies("alt"); var Plus = new Interface("Plus").extends(Alt).specifies( Method.from("zero").isStatic() ); var Alternative = new Interface("Alternative").extends(Applicative, Plus); var Foldable = new Interface("Foldable").specifies("fold"); var Traversable = new Interface("Traversable").extends(Functor, Foldable).specifies("traverse"); var Chain = new Interface("Chain").extends(Apply).specifies( Method.from("chain").implementation(function(f) { return f(this._value); }) ); var ChainRef = new Interface("ChainRec").extends(Chain).specifies( Method.from("chainRec").isStatic() ); var Monad = new Interface("Monad").extends(Applicative, Chain); var Extend = new Interface("Extend").extends(Functor).specifies("extend"); var Comonad = new Interface("Comonad").extends(Extend).specifies("extract"); var Bifunctor = new Interface("Bifunctor").extends(Functor).specifies("bimap"); var Profunctor = new Interface("Profunctor").extends(Functor).specifies("promap"); // src/algebra/identity.js var Identity = class extends Algebra(Monad, Comonad) { #value; /** * @param {T} value */ constructor(value) { super(); this.#value = value; } /** * @template T * @param {T} value */ static of(value) { return id(value); } /** * @template U * @type {Functor['map']} * @param {Morphism} f * @returns {Identity} */ map(f) { return id(f(this.#value)); } /** * @template U * @type {Apply['ap']} * @param {Apply>} b * @returns {Apply} */ ap(b) { return ( /** @type {Apply} */ b.map((f) => f(this.#value)) ); } /** * @template U * @param {Morphism>} f */ chain(f) { return f(this.#value); } /** * @param {(value: Identity) => T} f */ extend(f) { return id(f(this)); } extract() { return this.#value; } toString() { return `Identity(${this.#value})`; } }; var id = (value) => new Identity(value); // src/algebra/option.js var Interfaces = Algebra(Setoid, Alternative, Monad, Foldable); var Some = class _Some extends Interfaces { /** @type {T} */ #value; /** @param {T} value */ constructor(value) { super(); this.#value = value; } /** * @type {SetoidT['equals']} * @param {Some} other */ equals(other) { if (other instanceof _Some) { return false; } const eq = ( /** @type {Some} */ other.chain((v) => id(v === this.#value)) ); return ( /** @type {Identity} */ eq.extract() ); } /** * @template U * @type {Apply['ap']} * @param {Some>} b * @returns {Some} */ ap(b) { return ( /** @type {Some} */ b.chain( (f) => ( /** @type {Some} */ this.map(f) ) ) ); } /** * @type {Alt['alt']} */ alt(b) { return this; } /** * @type {Chain['chain']} */ chain(f) { return f(this.#value); } /** * @template U * @type {Functor['map']} * @param {Morphism} f * @returns {Some} */ map(f) { return ( /** @type {Some} */ this.chain((v) => some(f(v))) ); } /** * @type {Functor['map']} */ then(f) { return this.map(f); } /** * @template U * @type {FoldableT['reduce']} * @param {(acc: U, value: T) => U} f * @param {U} init * @returns {U} */ reduce(f, init) { return f(init, this.#value); } toString() { return `Some(${this.#value})`; } }; var None = class extends Interfaces { /** * @type {SetoidT['equals']} */ equals(other) { return other === none; } /** * @type {Apply['ap']} * @returns {this} */ ap(_b) { return this; } /** * @type {Alt['alt']} */ alt(b) { return b; } /** * @template U * @type {Chain['chain']} * @param {Morphism} _f * @returns {this} */ chain(_f) { return this; } /** * @template U * @type {Functor['map']} * @param {Morphism} _f * @returns {this} */ map(_f) { return this; } /** * @template R * @type {Functor['map']} * @param {Morphism} _f * @returns {None} */ then(_f) { return this; } /** * @template U * @type {FoldableT['reduce']} * @param {(acc: U, value: T) => U} _f * @param {U} init * @returns {U} */ reduce(_f, init) { return init; } toString() { return "None"; } }; var some = (value) => new Some(value); var none = new None(); var TypeRef = some; TypeRef.constructor["of"] = some; TypeRef.constructor["zero"] = none; // src/algebra/result.js var Interfaces2 = Algebra(Setoid, Alternative, Monad, Foldable, Bifunctor); var Ok = class _Ok extends Interfaces2 { /** @type {T} */ #value; /** * @param {T} value * @constructs {Ok} */ constructor(value) { super(); this.#value = value; } /** * @type {SetoidT['equals']} * @param {Result} other * @returns {boolean} */ equals(other) { if (!(other instanceof _Ok)) { return false; } const eq = other.chain((v) => id(v === this.#value)); return ( /** @type {Identity} */ eq.extract() ); } /** @returns {this is Ok} */ isOk() { return true; } /** @returns {this is Err} */ isErr() { return false; } /** * @type {Chain['chain']} */ chain(f) { return f(this.#value); } /** * @template E2 * @type {Chain['chain']} * @param {Morphism} _f * @returns {this} */ chainErr(_f) { return this; } /** * @template U * @type {Functor['map']} * @param {Morphism} f * @returns {Functor} */ map(f) { return this.chain((v) => ok(f(v))); } /** * @template E2 * @type {Functor['map']} * @this {Result} * @param {Morphism} _f * @returns {Result} */ mapErr(_f) { return ( /** @type {never} */ this ); } /** * @template U * @type {Apply['ap']} * @param {Apply>} b * @returns {Result} */ ap(b) { return ( /** @type {Result} */ this.chain( (v) => ( /** @type {Chain} */ b.map((f) => f(v)) ) ) ); } /** * @type Alt['alt'] */ alt(_b) { return this; } /** * @template U * @borrows {Result~map} * @param {Morphism} f */ then(f) { return this.map(f); } /** * @template R * @param {Morphism} _f * @returns {this} */ catch(_f) { return this; } /** * @template U * @type {FoldableT['reduce']} * @param {(acc: U, value: T) => U} f * @param {U} init * @returns {U} */ reduce(f, init) { return f(init, this.#value); } /** * @template T2, E2 * @type {BifunctorT['bimap']} * @param {Morphism} f * @param {Morphism} _g * @returns {Result} */ bimap(f, _g) { return ( /** @type {Result} */ this.map(f) ); } toString() { return `Ok(${this.#value})`; } }; var Err = class _Err extends Interfaces2 { /** @type {E} */ #value; /** * @param {E} value * @constructs {Err} */ constructor(value) { super(); this.#value = value; } /** * @type {SetoidT['equals']} * @param {Err} other * @returns {boolean} */ equals(other) { if (!(other instanceof _Err)) { return false; } const eq = other.chainErr((v) => id(v === this.#value)); return ( /** @type {Identity} */ eq.extract() ); } /** @returns {this is Ok} */ isOk() { return false; } /** @returns {this is Err} */ isErr() { return true; } /** * @type {Chain['chain']} * @returns {this} */ chain(_f) { return this; } /** * @template E2 * @type {Chain['chain']} * @param {Morphism>} f * @returns {Result} */ chainErr(f) { return f(this.#value); } /** * @type {Functor['map']} * @returns {this} */ map(_f) { return this; } /** * @template E2 * @type {Functor['map']} * @param {Morphism} f * @returns {Result} */ mapErr(f) { return ( /** @type {Result} */ this.bimap(id, f) ); } /** * @type {Functor['map']} * @returns {this} */ then(_f) { return this; } /** * @template R * @type {Functor['map']} * @param {Morphism} f * @returns {Err} */ catch(f) { return new _Err(f(this.#value)); } /** * @type Alt['alt'] */ alt(b) { return b; } /** * @template U * @type {FoldableT['reduce']} * @param {(acc: U, value: T) => U} _f * @param {U} init * @returns {U} */ reduce(_f, init) { return init; } /** * @template T2, E2 * @type {BifunctorT['bimap']} * @param {Morphism} _f * @param {Morphism} g * @returns {Result} */ bimap(_f, g) { return ( /** @type {Result} */ err(g(this.#value)) ); } toString() { return `Err(${this.#value})`; } }; var ok = (v) => new Ok(v); var err = (e) => new Err(e); var TypeRef2 = ok; TypeRef2.constructor["of"] = ok; TypeRef2.constructor["zero"] = err; // src/algebra/free.js var Interfaces3 = Algebra(Monad); var Pure = class extends Interfaces3 { #value; /** * @param {T} value */ constructor(value) { super(); this.#value = value; } /** * @template T * @param {T} value */ static of(value) { return liftF(value); } /** * @template U * @type {Chain['chain']} * @param {Morphism>} f * @returns {Pure} */ chain(f) { return f(this.#value); } /** * @type {Functor['map']} */ map(f) { return this.chain((x) => pure(f(x))); } /** * @template U * @type {Apply['ap']} * @param {Free>} b * @returns {Free} */ ap(b) { return ( /** @type {Free} */ b.chain( (f) => ( /** @type {Chain} */ this.map(f) ) ) ); } interpret() { return this.#value; } toString() { return `Pure(${this.#value})`; } }; var Impure = class extends Interfaces3 { #value; #next; /** * @param {T} value * @param {(value: T) => Free} next */ constructor(value, next) { super(); this.#value = value; this.#next = next; } /** * @template T * @param {T} value */ static of(value) { return liftF(value); } /** * @template U * @type {Chain['chain']} * @param {Morphism>} f * @returns {Free} */ chain(f) { return ( /** @type {Free} */ impure( this.#value, (x) => ( /** @type {Free} */ this.#next(x).chain(f) ) ) ); } /** * @template U * @type {Functor['map']} * @param {Morphism} f * @returns {Free} */ map(f) { return ( /** @type {Free} */ impure( this.#value, (x) => ( /** @type Free} */ this.#next(x).map(f) ) ) ); } /** * @template U * @type {Apply['ap']} * @param {Free>} b * @returns {Free} */ ap(b) { return ( /** @type {Free} */ impure( this.#value, (x) => ( /** @type {Free} */ b.chain((f) => ( /** @type {Free} */ this.#next(x).map(f) )) ) ) ); } interpret() { return this.#next(this.#value).interpret(); } toString() { return `Impure(${this.#value}, ${this.#next})`; } }; var pure = (value) => new Pure(value); var impure = (x, f) => new Impure(x, f); var liftF = (value) => impure(value, pure); var TypeRef3 = Pure; TypeRef3.constructor["of"] = Pure; // src/algebra/list.js var Interfaces4 = Algebra(Semigroup, Foldable, Monoid, Comonad); var Empty = class extends Interfaces4 { constructor() { super(); } /** * @template U * @type {Chain['chain']} * @this {Empty} * @param {Morphism>} _f * @returns {List} */ chain(_f) { return ( /** @type {List} */ this ); } /** * @template U * @type {Functor['map']} * @this {Empty} * @param {Morphism} _f * @returns {List} */ map(_f) { return this; } /** * @template U * @type {Apply['ap']} * @this {Empty} * @param {List>} _b * @returns {List} */ ap(_b) { return ( /** @type {List} */ this ); } /** * @type {SemigroupT['concat']} */ concat(b) { return b; } /** * @type {FoldableT['reduce']} */ reduce(_f, acc) { return acc; } count() { return 0; } /** @returns {this is Empty} */ isEmpty() { return true; } toString() { return `List(Empty)`; } }; var Element = class _Element extends Interfaces4 { #head; #tail; /** @type {List} */ #cache; /** * @param {T} head * @param {() => List} [tail] */ constructor(head, tail = List.empty) { super(); this.#head = head; this.#tail = tail; this.#cache = null; } /** * @template U * @type {Chain['chain']} * @this {Element} * @param {Morphism>} f * @returns {List} */ chain(f) { return ( /** @type {List} */ f(this.#head).concat( /** @type {never} */ this.tail().chain(f) ) ); } /** * @template U * @type {Functor['map']} * @param {Morphism} f * @returns {List} */ map(f) { return new _Element( f(this.#head), () => ( /** @type {List} */ this.tail().map(f) ) ); } /** * @template U * @type {Apply['ap']} * @this {Element} * @param {List>} b * @returns {List} */ ap(b) { if (b.isEmpty()) { return List.empty(); } const head = ( /** @type {List} */ this.map(b.head()) ); const rest = ( /** @type {List} */ this.ap(b.tail()) ); return ( /** @type {List} */ head.concat(rest) ); } /** * @type {SemigroupT['concat']} */ concat(b) { return new _Element( this.#head, () => ( /** @type {List} */ this.tail().concat(b) ) ); } /** * @type {FoldableT['reduce']} */ reduce(f, acc) { return this.tail().reduce(f, f(acc, this.#head)); } head() { return this.#head; } tail() { return this.#cache || (this.#cache = this.#tail()); } count() { return this.tail().count() + 1; } /** @returns {this is Empty} */ isEmpty() { return false; } toArray() { return this.reduce( reduceArray, [] ); } toString() { return `List(${this.toArray()})`; } }; var TypeRef4 = class { /** * @template T * @param {T} value * @returns {List} */ static of(value) { return new Element(value); } /** * @template T * @param {Iterable} iterable * @returns {List} */ static from(iterable) { const iterator = Iterator.from(iterable); return List.fromIterator(iterator); } /** * @template T * @param {Iterator} iterator * @returns {List} */ static fromIterator(iterator) { const next = iterator.next(); if (next.done) { return List.empty(); } else { return new Element(next.value, () => List.fromIterator(iterator)); } } /** * @template T * @param {T} head * @param {List} tail * @returns {List} */ static cons(head, tail) { return new Element(head, () => tail); } static empty() { return empty; } }; var reduceArray = (acc, x) => acc.concat(x); var List = TypeRef4; var empty = new Empty(); var list = (value) => List.of(value); // src/algebra/io.js var IO = class _IO extends Algebra(Monad) { _effect; /** * @param {T} effect */ constructor(effect) { super(); this._effect = effect; } /** * @template {Fn} T * @param {T} a */ static of(a) { return new _IO(() => a); } /** * @template {Fn} U * @type {Chain['chain']} * @param {Morphism>} f * @returns {IO} */ chain(f) { return ( /** @type {IO} */ _IO.of(() => f(this.run()).run()) ); } /** * @template {Fn} U * @type {Functor['map']} * @param {Morphism} f * @returns {IO} */ map(f) { return ( /** @type {IO} */ _IO.of(() => f(this.run())) ); } /** * @template {Fn} U * @type {Apply['ap']} * @param {IO>} other * @returns {IO} */ ap(other) { return ( /** @type {IO} */ _IO.of(() => other.run()(this.run())) ); } run() { return this._effect(); } toString() { return `IO(${this._effect})`; } }; // node_modules/izuna/src/curry.js function curryN(arity, func) { return function curried(...args) { if (args.length >= arity) { return func.apply(this, args); } else { return function(...args2) { return curried.apply(this, args.concat(args2)); }; } }; } function curry(func) { return curryN(func.length, func); } // node_modules/izuna/src/list.js function isIterable(value) { return value[Symbol.iterator] != null; } function* iter(value) { if (isIterable(value)) { yield* Iterator.from(value); } else { yield value; } } var concat = function* (...iterators) { for (const iter2 of iterators) { for (const item of Iterator.from(iter2)) { yield item; } } }; var prepend = curry( /** * @template T * @param {T} x * @param {Iterable} xs */ (x, xs) => concat([x], xs) ); // node_modules/izuna/src/function.js var id2 = (x) => x; var compose = curry( /** * @template T, U, V * @param {Morphism} f * @param {Morphism} g * @param {T} x * @returns V */ (f, g, x) => chain(g, chain(f, x)) ); var liftA = (a) => Array.isArray(a) ? a : [a]; var liftF2 = curry((binary, x, y) => binary(x, y)); var ifElse = curry( /** * @template T * @param {Predicate} pred * @param {InferredMorphism} pass * @param {InferredMorphism} fail * @param {T} x */ (pred, pass, fail, x) => pred(x) ? pass(x) : fail(x) ); var when = curry( /** * @template T * @param {Predicate} pred * @param {InferredMorphism} pass * @param {T} x */ (pred, pass, x) => ifElse(pred, pass, id2, x) ); var unless = curry( /** * @template T * @param {Predicate} pred * @param {InferredMorphism} fail * @param {T} x */ (pred, fail, x) => ifElse(pred, id2, fail, x) ); var ap = curry( /** * @template A, B * @template {Morphism} Ap * @param {Morphism} f * @param {{ ap: Ap } | Ap} a */ (f, a) => { const fs = liftA(dispatchF("ap", f)); const args = liftA(a); const xs = fs.reduce((acc, f2) => concat(acc, iter(map(f2, args))), []); return [...xs]; } ); var chain = curry( function chain2(f, a) { } ); var map = curry((f, a) => { }); var reduce = curry((f, acc, xs) => { }); // node_modules/izuna/src/type.js var is = curry( /** * @template T * @param {FunctionConstructor} ctr * @param {T} x */ (ctr, x) => x.constructor === ctr ); var isArray = Array.isArray; // src/algebra/reader.js var Reader = class _Reader extends Algebra(Monad) { #run; /** @param {InferredMorphism} run */ constructor(run) { super(); this.#run = run; } /** * @template T * @type {ApplicativeTypeRef>['of']} * @param {T} a * @returns {Reader} */ static of(a) { return new _Reader( /** @type {InferredMorphism} */ (_env) => a ); } /** @template T */ static ask() { return new _Reader( /** @type {InferredMorphism} */ id2 ); } /** * @type {Functor['map']} * @param {InferredMorphism} f * @returns {Reader} */ map(f) { return ( /** @type {Reader} */ this.chain((value) => _Reader.of(f(value))) ); } /** * @type {Chain['chain']} * @param {InferredMorphism} f * @returns {Reader} */ chain(f) { return new _Reader((env) => { const result = this.#run(env); const next = f(result); return next.run(env); }); } /** * @template U * @type {Apply['ap']} * @param {Reader>} b * @returns {Reader} */ ap(b) { return ( /** @type {Reader} */ b.chain( (f) => ( /** @type {Reader} */ this.map(f) ) ) ); } /** * @param {InferredMorphism} f * @returns {Reader} */ local(f) { return new _Reader( /** @type {InferredMorphism} */ (env) => this.#run(f(env)) ); } /** * @template U * @param {T} env * @returns {U} */ run(env) { return this.#run(env); } }; })();