1712 lines
39 KiB
JavaScript
1712 lines
39 KiB
JavaScript
"use strict";
|
|
(() => {
|
|
// src/iter.js
|
|
var Iter = class _Iter {
|
|
_iterator;
|
|
_source;
|
|
/**
|
|
* @param {Iterator<T>} iterator
|
|
* @param {Iterabl<T>} [source]
|
|
*/
|
|
constructor(iterator, source) {
|
|
this._iterator = iterator;
|
|
this._source = source;
|
|
}
|
|
/**
|
|
* @template T
|
|
* @param {any} value
|
|
* @returns {value is Iterable<T>}
|
|
*/
|
|
static _isIterable(value) {
|
|
return typeof value[Symbol.iterator] === "function";
|
|
}
|
|
/**
|
|
* @template T
|
|
* @param {T} value
|
|
*/
|
|
static from(value) {
|
|
if (value instanceof _Iter) {
|
|
return value;
|
|
}
|
|
if (_Iter._isIterable(value)) {
|
|
const iterator = value[Symbol.iterator]();
|
|
if (iterator instanceof _Iter) {
|
|
return iterator;
|
|
}
|
|
return new _Iter(iterator, value);
|
|
}
|
|
throw new TypeError("object is not an iterator");
|
|
}
|
|
clone() {
|
|
if (this._source) {
|
|
return _Iter.from(this._source);
|
|
}
|
|
throw new Error("Cannot clone Iterator: not created from an iterable");
|
|
}
|
|
/**
|
|
* @param {any} [value]
|
|
*/
|
|
next(value) {
|
|
const n = this._iterator.next(value);
|
|
return n;
|
|
}
|
|
/**
|
|
* @param {any} [value]
|
|
*/
|
|
return(value) {
|
|
return this._iterator.return(value);
|
|
}
|
|
/**
|
|
* @param {any} err
|
|
*/
|
|
throw(err2) {
|
|
return this._iterator.throw(err2);
|
|
}
|
|
/**
|
|
* @param {number} limit
|
|
*/
|
|
drop(limit) {
|
|
return new DropIter(this, limit);
|
|
}
|
|
/**
|
|
* @param {(value: T, index: number) => boolean} callbackFn
|
|
*/
|
|
every(callbackFn) {
|
|
let next2 = this.next();
|
|
let index = 0;
|
|
let result = true;
|
|
while (!next2.done) {
|
|
if (!callbackFn(next2.value, index)) {
|
|
result = false;
|
|
break;
|
|
}
|
|
next2 = this.next();
|
|
index += 1;
|
|
}
|
|
this.return();
|
|
return result;
|
|
}
|
|
/**
|
|
* @param {(value: T, index: number) => boolean} callbackFn
|
|
*/
|
|
filter(callbackFn) {
|
|
return new FilterIter(this, callbackFn);
|
|
}
|
|
/**
|
|
* @param {(value: T, index: number) => boolean} callbackFn
|
|
*/
|
|
find(callbackFn) {
|
|
let next2 = this.next();
|
|
let index = 0;
|
|
while (!next2.done) {
|
|
if (callbackFn(next2.value, index)) {
|
|
this.return();
|
|
return next2.value;
|
|
}
|
|
next2 = this.next();
|
|
index += 1;
|
|
}
|
|
}
|
|
/**
|
|
* @param {<U>(value: T, index: number) => U} callbackFn
|
|
*/
|
|
flatMap(callbackFn) {
|
|
return new FlatMapIter(this, callbackFn);
|
|
}
|
|
/**
|
|
* @param {(value: T, index: number) => void} callbackFn
|
|
*/
|
|
forEach(callbackFn) {
|
|
let next2 = this.next();
|
|
let index = 0;
|
|
while (!next2.done) {
|
|
callbackFn(next2.value, index);
|
|
next2 = this.next();
|
|
index += 1;
|
|
}
|
|
}
|
|
/**
|
|
* @param {<U>(value: T, index: number) => U} callbackFn
|
|
*/
|
|
map(callbackFn) {
|
|
return new MapIter(this, callbackFn);
|
|
}
|
|
/**
|
|
* @template U
|
|
* @param {(accumulator: U, value: T, index: number) => U} callbackFn
|
|
* @param {U} init
|
|
*/
|
|
reduce(callbackFn, init) {
|
|
let next2 = this.next();
|
|
let index = 0;
|
|
let acc = init;
|
|
while (!next2.done) {
|
|
acc = callbackFn(acc, next2.value, index);
|
|
next2 = this.next();
|
|
index += 1;
|
|
}
|
|
this.return();
|
|
return acc;
|
|
}
|
|
/**
|
|
* @param {(value: T, index: number) => boolean} callbackFn
|
|
*/
|
|
some(callbackFn) {
|
|
let next2 = this.next();
|
|
let index = 0;
|
|
let result = false;
|
|
while (!next2.done) {
|
|
if (callbackFn(next2.value, index)) {
|
|
result = true;
|
|
break;
|
|
}
|
|
next2 = this.next();
|
|
index += 1;
|
|
}
|
|
this.return();
|
|
return result;
|
|
}
|
|
/**
|
|
* @param {number} limit
|
|
*/
|
|
take(limit) {
|
|
return new TakeIter(this, limit);
|
|
}
|
|
/*
|
|
* @returns {T[]}
|
|
*/
|
|
toArray() {
|
|
const result = [];
|
|
for (const item of this) {
|
|
result.push(item);
|
|
}
|
|
return result;
|
|
}
|
|
*[Symbol.iterator]() {
|
|
return this;
|
|
}
|
|
};
|
|
var DropIter = class extends Iter {
|
|
_limit;
|
|
/**
|
|
* @param {Iterator<T>} iterator
|
|
* @param {number} limit
|
|
*/
|
|
constructor(iterator, limit) {
|
|
super(iterator);
|
|
this._limit = limit;
|
|
}
|
|
/**
|
|
* @param {any} value
|
|
*/
|
|
next(value) {
|
|
for (let i = this._limit; i > 0; i--) {
|
|
const next2 = super.next(value);
|
|
if (next2.done) {
|
|
return next2;
|
|
}
|
|
}
|
|
return super.next(value);
|
|
}
|
|
};
|
|
var FilterIter = class extends Iter {
|
|
_filter;
|
|
_index = 0;
|
|
/**
|
|
* @param {Iterator<T>} iterator
|
|
* @param {(value: T, index: number) => boolean} callbackFn
|
|
*/
|
|
constructor(iterator, callbackFn) {
|
|
super(iterator);
|
|
this._filter = callbackFn;
|
|
}
|
|
/**
|
|
* @param {any} [value]
|
|
* @returns {IteratorResult<T>}
|
|
*/
|
|
next(value) {
|
|
let next2 = super.next(value);
|
|
while (!next2.done && !this._filter(next2.value, this._index)) {
|
|
next2 = super.next(value);
|
|
this._index += 1;
|
|
}
|
|
return next2;
|
|
}
|
|
};
|
|
var FlatMapIter = class extends Iter {
|
|
_flatMap;
|
|
_index = 0;
|
|
/** @type {Iterator<T> | undefined} */
|
|
_inner = void 0;
|
|
/**
|
|
* @param {Iterator<T>} iterator
|
|
* @param {<U>(value: T, index: number) => Iterator<U> | Iterable<U>} callbackFn
|
|
*/
|
|
constructor(iterator, callbackFn) {
|
|
super(iterator);
|
|
this._flatMap = callbackFn;
|
|
}
|
|
/**
|
|
* @param {any} value
|
|
* @returns {IteratorResult<T>}
|
|
*/
|
|
next(value) {
|
|
if (this._inner) {
|
|
const innerResult = this._inner.next(value);
|
|
if (!innerResult.done) {
|
|
this._index += 1;
|
|
return { value: innerResult.value, done: false };
|
|
}
|
|
this._inner = void 0;
|
|
}
|
|
const outerResult = super.next(value);
|
|
if (outerResult.done) {
|
|
return { value: void 0, done: true };
|
|
}
|
|
const nextIterable = this._flatMap(outerResult.value, this._index || 0);
|
|
if (Iter._isIterable(nextIterable)) {
|
|
this._inner = Iter.from(nextIterable);
|
|
return this.next(value);
|
|
} else {
|
|
throw new TypeError("value is not an iterator");
|
|
}
|
|
}
|
|
};
|
|
var MapIter = class extends Iter {
|
|
_map;
|
|
_index = 0;
|
|
/**
|
|
* @param {Iterator<T>} iterator
|
|
* @param {<U>(value: T, index: number) => U} callbackFn
|
|
*/
|
|
constructor(iterator, callbackFn) {
|
|
super(iterator);
|
|
this._map = callbackFn;
|
|
}
|
|
/** @param {any} value */
|
|
next(value) {
|
|
let next2 = super.next(value);
|
|
if (next2.done) {
|
|
return next2;
|
|
}
|
|
const result = {
|
|
done: false,
|
|
value: this._map(next2.value, this._index)
|
|
};
|
|
this._index += 1;
|
|
return result;
|
|
}
|
|
};
|
|
var TakeIter = class extends Iter {
|
|
_limit;
|
|
/**
|
|
* @param {Iterator<T>} iterator
|
|
* @param {number} limit
|
|
*/
|
|
constructor(iterator, limit) {
|
|
super(iterator);
|
|
this._limit = limit;
|
|
}
|
|
/**
|
|
* @param {any} value
|
|
* @returns {IteratorResult<T>}
|
|
*/
|
|
next(value) {
|
|
if (this._limit > 0) {
|
|
const next2 = super.next(value);
|
|
if (!next2.done) {
|
|
this._limit -= 1;
|
|
}
|
|
return next2;
|
|
}
|
|
return { value: void 0, done: true };
|
|
}
|
|
};
|
|
|
|
// node_modules/kojima/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.<MixinFunction>} mixins
|
|
* @return {FunctionConstructor} a subclass of `superclass` with `mixins` applied
|
|
*/
|
|
with(...mixins) {
|
|
return mixins.reduce((c, m) => m(c), this.superclass);
|
|
}
|
|
};
|
|
|
|
// node_modules/kojima/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<Method>} */
|
|
#methods = /* @__PURE__ */ new Set();
|
|
/** @type {Set<Interface>} */
|
|
#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");
|
|
|
|
// node_modules/kojima/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<T>['map']}
|
|
* @param {Morphism<T, U>} f
|
|
* @returns {Identity<U>}
|
|
*/
|
|
map(f) {
|
|
return id(f(this.#value));
|
|
}
|
|
/**
|
|
* @template U
|
|
* @type {Apply<T>['ap']}
|
|
* @param {Apply<Morphism<T, U>>} b
|
|
* @returns {Apply<U>}
|
|
*/
|
|
ap(b) {
|
|
return (
|
|
/** @type {Apply<U>} */
|
|
b.map((f) => f(this.#value))
|
|
);
|
|
}
|
|
/**
|
|
* @template U
|
|
* @param {Morphism<T, Identity<U>>} f
|
|
*/
|
|
chain(f) {
|
|
return f(this.#value);
|
|
}
|
|
/**
|
|
* @param {(value: Identity<T>) => T} f
|
|
*/
|
|
extend(f) {
|
|
return id(f(this));
|
|
}
|
|
extract() {
|
|
return this.#value;
|
|
}
|
|
toString() {
|
|
return `Identity(${this.#value})`;
|
|
}
|
|
};
|
|
var id = (value) => new Identity(value);
|
|
|
|
// node_modules/kojima/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<T>['equals']}
|
|
* @param {Some<T>} other
|
|
*/
|
|
equals(other) {
|
|
if (other instanceof _Some) {
|
|
return false;
|
|
}
|
|
const eq = (
|
|
/** @type {Some<T>} */
|
|
other.chain((v) => id(v === this.#value))
|
|
);
|
|
return (
|
|
/** @type {Identity<boolean>} */
|
|
eq.extract()
|
|
);
|
|
}
|
|
/**
|
|
* @template U
|
|
* @type {Apply<T>['ap']}
|
|
* @param {Some<Morphism<T, U>>} b
|
|
* @returns {Some<U>}
|
|
*/
|
|
ap(b) {
|
|
return (
|
|
/** @type {Some<U>} */
|
|
b.chain(
|
|
(f) => (
|
|
/** @type {Some<U>} */
|
|
this.map(f)
|
|
)
|
|
)
|
|
);
|
|
}
|
|
/**
|
|
* @type {Alt<T>['alt']}
|
|
*/
|
|
alt(b) {
|
|
return this;
|
|
}
|
|
/**
|
|
* @type {Chain<T>['chain']}
|
|
*/
|
|
chain(f) {
|
|
return f(this.#value);
|
|
}
|
|
/**
|
|
* @template U
|
|
* @type {Functor<T>['map']}
|
|
* @param {Morphism<T, U>} f
|
|
* @returns {Some<U>}
|
|
*/
|
|
map(f) {
|
|
return (
|
|
/** @type {Some<U>} */
|
|
this.chain((v) => some(f(v)))
|
|
);
|
|
}
|
|
/**
|
|
* @type {Functor<T>['map']}
|
|
*/
|
|
then(f) {
|
|
return this.map(f);
|
|
}
|
|
/**
|
|
* @template U
|
|
* @type {FoldableT<T>['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<T>['equals']}
|
|
*/
|
|
equals(other) {
|
|
return other === none;
|
|
}
|
|
/**
|
|
* @type {Apply<T>['ap']}
|
|
* @returns {this}
|
|
*/
|
|
ap(_b) {
|
|
return this;
|
|
}
|
|
/**
|
|
* @type {Alt<T>['alt']}
|
|
*/
|
|
alt(b) {
|
|
return b;
|
|
}
|
|
/**
|
|
* @template U
|
|
* @type {Chain<T>['chain']}
|
|
* @param {Morphism<T, U>} _f
|
|
* @returns {this}
|
|
*/
|
|
chain(_f) {
|
|
return this;
|
|
}
|
|
/**
|
|
* @template U
|
|
* @type {Functor<T>['map']}
|
|
* @param {Morphism<T, U>} _f
|
|
* @returns {this}
|
|
*/
|
|
map(_f) {
|
|
return this;
|
|
}
|
|
/**
|
|
* @template R
|
|
* @type {Functor<T>['map']}
|
|
* @param {Morphism<T, R>} _f
|
|
* @returns {None}
|
|
*/
|
|
then(_f) {
|
|
return this;
|
|
}
|
|
/**
|
|
* @template U
|
|
* @type {FoldableT<T>['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;
|
|
|
|
// node_modules/kojima/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<T, E>}
|
|
*/
|
|
constructor(value) {
|
|
super();
|
|
this.#value = value;
|
|
}
|
|
/**
|
|
* @type {SetoidT<T>['equals']}
|
|
* @param {Result<T, E>} other
|
|
* @returns {boolean}
|
|
*/
|
|
equals(other) {
|
|
if (!(other instanceof _Ok)) {
|
|
return false;
|
|
}
|
|
const eq = other.chain((v) => id(v === this.#value));
|
|
return (
|
|
/** @type {Identity<boolean>} */
|
|
eq.extract()
|
|
);
|
|
}
|
|
/** @returns {this is Ok<T, E>} */
|
|
isOk() {
|
|
return true;
|
|
}
|
|
/** @returns {this is Err<T, E>} */
|
|
isErr() {
|
|
return false;
|
|
}
|
|
/**
|
|
* @type {Chain<T>['chain']}
|
|
*/
|
|
chain(f) {
|
|
return f(this.#value);
|
|
}
|
|
/**
|
|
* @template E2
|
|
* @type {Chain<E>['chain']}
|
|
* @param {Morphism<E, E2>} _f
|
|
* @returns {this}
|
|
*/
|
|
chainErr(_f) {
|
|
return this;
|
|
}
|
|
/**
|
|
* @template U
|
|
* @type {Functor<T>['map']}
|
|
* @param {Morphism<T, U>} f
|
|
* @returns {Functor<U>}
|
|
*/
|
|
map(f) {
|
|
return this.chain((v) => ok(f(v)));
|
|
}
|
|
/**
|
|
* @template E2
|
|
* @type {Functor<E>['map']}
|
|
* @this {Result<T, E>}
|
|
* @param {Morphism<E, E2>} _f
|
|
* @returns {Result<T, E2>}
|
|
*/
|
|
mapErr(_f) {
|
|
return (
|
|
/** @type {never} */
|
|
this
|
|
);
|
|
}
|
|
/**
|
|
* @template U
|
|
* @type {Apply<T>['ap']}
|
|
* @param {Apply<Morphism<T, U>>} b
|
|
* @returns {Result<U, E>}
|
|
*/
|
|
ap(b) {
|
|
return (
|
|
/** @type {Result<U, E>} */
|
|
this.chain(
|
|
(v) => (
|
|
/** @type {Chain<U>} */
|
|
b.map((f) => f(v))
|
|
)
|
|
)
|
|
);
|
|
}
|
|
/**
|
|
* @type Alt<T>['alt']
|
|
*/
|
|
alt(_b) {
|
|
return this;
|
|
}
|
|
/**
|
|
* @template U
|
|
* @borrows {Result~map}
|
|
* @param {Morphism<T, U>} f
|
|
*/
|
|
then(f) {
|
|
return this.map(f);
|
|
}
|
|
/**
|
|
* @template R
|
|
* @param {Morphism<E, R>} _f
|
|
* @returns {this}
|
|
*/
|
|
catch(_f) {
|
|
return this;
|
|
}
|
|
/**
|
|
* @template U
|
|
* @type {FoldableT<T>['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<T, E>['bimap']}
|
|
* @param {Morphism<T, T2>} f
|
|
* @param {Morphism<E, E2>} _g
|
|
* @returns {Result<T2, E2>}
|
|
*/
|
|
bimap(f, _g) {
|
|
return (
|
|
/** @type {Result<T2, E2>} */
|
|
this.map(f)
|
|
);
|
|
}
|
|
toString() {
|
|
return `Ok(${this.#value})`;
|
|
}
|
|
};
|
|
var Err = class _Err extends Interfaces2 {
|
|
/** @type {E} */
|
|
#value;
|
|
/**
|
|
* @param {E} value
|
|
* @constructs {Err<T, E>}
|
|
*/
|
|
constructor(value) {
|
|
super();
|
|
this.#value = value;
|
|
}
|
|
/**
|
|
* @type {SetoidT<T>['equals']}
|
|
* @param {Err<T, E>} other
|
|
* @returns {boolean}
|
|
*/
|
|
equals(other) {
|
|
if (!(other instanceof _Err)) {
|
|
return false;
|
|
}
|
|
const eq = other.chainErr((v) => id(v === this.#value));
|
|
return (
|
|
/** @type {Identity<boolean>} */
|
|
eq.extract()
|
|
);
|
|
}
|
|
/** @returns {this is Ok<T, E>} */
|
|
isOk() {
|
|
return false;
|
|
}
|
|
/** @returns {this is Err<T, E>} */
|
|
isErr() {
|
|
return true;
|
|
}
|
|
/**
|
|
* @type {Chain<T>['chain']}
|
|
* @returns {this}
|
|
*/
|
|
chain(_f) {
|
|
return this;
|
|
}
|
|
/**
|
|
* @template E2
|
|
* @type {Chain<E>['chain']}
|
|
* @param {Morphism<E, Result<T, E2>>} f
|
|
* @returns {Result<T, E2>}
|
|
*/
|
|
chainErr(f) {
|
|
return f(this.#value);
|
|
}
|
|
/**
|
|
* @type {Functor<T>['map']}
|
|
* @returns {this}
|
|
*/
|
|
map(_f) {
|
|
return this;
|
|
}
|
|
/**
|
|
* @template E2
|
|
* @type {Functor<E>['map']}
|
|
* @param {Morphism<E, E2>} f
|
|
* @returns {Result<T, E2>}
|
|
*/
|
|
mapErr(f) {
|
|
return (
|
|
/** @type {Result<T, E2>} */
|
|
this.bimap(id, f)
|
|
);
|
|
}
|
|
/**
|
|
* @type {Functor<T>['map']}
|
|
* @returns {this}
|
|
*/
|
|
then(_f) {
|
|
return this;
|
|
}
|
|
/**
|
|
* @template R
|
|
* @type {Functor<E>['map']}
|
|
* @param {Morphism<E, R>} f
|
|
* @returns {Err<T, R>}
|
|
*/
|
|
catch(f) {
|
|
return new _Err(f(this.#value));
|
|
}
|
|
/**
|
|
* @type Alt<T>['alt']
|
|
*/
|
|
alt(b) {
|
|
return b;
|
|
}
|
|
/**
|
|
* @template U
|
|
* @type {FoldableT<T>['reduce']}
|
|
* @param {(acc: U, value: T) => U} _f
|
|
* @param {U} init
|
|
* @returns {U}
|
|
*/
|
|
reduce(_f, init) {
|
|
return init;
|
|
}
|
|
/**
|
|
* @template T2, E2
|
|
* @type {BifunctorT<T, E>['bimap']}
|
|
* @param {Morphism<T, T2>} _f
|
|
* @param {Morphism<E, E2>} g
|
|
* @returns {Result<T2, E2>}
|
|
*/
|
|
bimap(_f, g) {
|
|
return (
|
|
/** @type {Result<T2, E2>} */
|
|
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;
|
|
|
|
// node_modules/kojima/src/algebra/list.js
|
|
var Interfaces3 = Algebra(Semigroup, Foldable, Monoid, Comonad);
|
|
var Empty = class extends Interfaces3 {
|
|
constructor() {
|
|
super();
|
|
}
|
|
/**
|
|
* @template U
|
|
* @type {Chain<T>['chain']}
|
|
* @this {Empty<U>}
|
|
* @param {Morphism<T, List<U>>} _f
|
|
* @returns {List<U>}
|
|
*/
|
|
chain(_f) {
|
|
return (
|
|
/** @type {List<U>} */
|
|
this
|
|
);
|
|
}
|
|
/**
|
|
* @template U
|
|
* @type {Functor<T>['map']}
|
|
* @this {Empty<U>}
|
|
* @param {Morphism<T, U>} _f
|
|
* @returns {List<U>}
|
|
*/
|
|
map(_f) {
|
|
return this;
|
|
}
|
|
/**
|
|
* @template U
|
|
* @type {Apply<T>['ap']}
|
|
* @this {Empty<U>}
|
|
* @param {List<Morphism<T, U>>} _b
|
|
* @returns {List<U>}
|
|
*/
|
|
ap(_b) {
|
|
return (
|
|
/** @type {List<U>} */
|
|
this
|
|
);
|
|
}
|
|
/**
|
|
* @type {SemigroupT<T>['concat']}
|
|
*/
|
|
concat(b) {
|
|
return b;
|
|
}
|
|
/**
|
|
* @type {FoldableT<T>['reduce']}
|
|
*/
|
|
reduce(_f, acc) {
|
|
return acc;
|
|
}
|
|
count() {
|
|
return 0;
|
|
}
|
|
/** @returns {this is Empty<T>} */
|
|
isEmpty() {
|
|
return true;
|
|
}
|
|
toString() {
|
|
return `List(Empty)`;
|
|
}
|
|
};
|
|
var empty = new Empty();
|
|
|
|
// node_modules/kojima/src/algebra/free.js
|
|
var Interfaces4 = Algebra(Monad);
|
|
|
|
// node_modules/kojima/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<T>['chain']}
|
|
* @param {Morphism<T, IO<U>>} f
|
|
* @returns {IO<U>}
|
|
*/
|
|
chain(f) {
|
|
return (
|
|
/** @type {IO<U>} */
|
|
_IO.of(() => f(this.run()).run())
|
|
);
|
|
}
|
|
/**
|
|
* @template {Fn} U
|
|
* @type {Functor<T>['map']}
|
|
* @param {Morphism<T, U>} f
|
|
* @returns {IO<U>}
|
|
*/
|
|
map(f) {
|
|
return (
|
|
/** @type {IO<U>} */
|
|
_IO.of(() => f(this.run()))
|
|
);
|
|
}
|
|
/**
|
|
* @template {Fn} U
|
|
* @type {Apply<T>['ap']}
|
|
* @param {IO<Morphism<T, U>>} other
|
|
* @returns {IO<U>}
|
|
*/
|
|
ap(other) {
|
|
return (
|
|
/** @type {IO<U>} */
|
|
_IO.of(() => other.run()(this.run()))
|
|
);
|
|
}
|
|
run() {
|
|
return this._effect();
|
|
}
|
|
toString() {
|
|
return `IO(${this._effect})`;
|
|
}
|
|
};
|
|
|
|
// node_modules/kojima/vendor/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/kojima/vendor/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 iter3 of iterators) {
|
|
for (const item of Iterator.from(iter3)) {
|
|
yield item;
|
|
}
|
|
}
|
|
};
|
|
var prepend = curry(
|
|
/**
|
|
* @template T
|
|
* @param {T} x
|
|
* @param {Iterable<T>} xs
|
|
*/
|
|
(x, xs) => concat([x], xs)
|
|
);
|
|
|
|
// node_modules/kojima/vendor/izuna/src/function.js
|
|
var id2 = (x) => x;
|
|
var compose = curry(
|
|
/**
|
|
* @template T, U, V
|
|
* @param {Morphism<U, V>} f
|
|
* @param {Morphism<T, U>} g
|
|
* @param {T} x
|
|
* @returns V
|
|
*/
|
|
(f, g, x) => chain(g, chain(f, x))
|
|
);
|
|
var liftA = (a) => Array.isArray(a) ? a : [a];
|
|
var liftF = curry((binary, x, y) => binary(x, y));
|
|
var ifElse = curry(
|
|
/**
|
|
* @template T
|
|
* @param {Predicate<T>} pred
|
|
* @param {InferredMorphism<T>} pass
|
|
* @param {InferredMorphism<T>} fail
|
|
* @param {T} x
|
|
*/
|
|
(pred, pass, fail2, x) => pred(x) ? pass(x) : fail2(x)
|
|
);
|
|
var when = curry(
|
|
/**
|
|
* @template T
|
|
* @param {Predicate<T>} pred
|
|
* @param {InferredMorphism<T>} pass
|
|
* @param {T} x
|
|
*/
|
|
(pred, pass, x) => ifElse(pred, pass, id2, x)
|
|
);
|
|
var unless = curry(
|
|
/**
|
|
* @template T
|
|
* @param {Predicate<T>} pred
|
|
* @param {InferredMorphism<T>} fail
|
|
* @param {T} x
|
|
*/
|
|
(pred, fail2, x) => ifElse(pred, id2, fail2, x)
|
|
);
|
|
var ap = curry(
|
|
/**
|
|
* @template A, B
|
|
* @template {Morphism<A, B>} Ap
|
|
* @param {Morphism<A, B>} 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/kojima/vendor/izuna/src/type.js
|
|
var is = curry(
|
|
/**
|
|
* @template T
|
|
* @param {FunctionConstructor} ctr
|
|
* @param {T} x
|
|
*/
|
|
(ctr, x) => x.constructor === ctr
|
|
);
|
|
var isArray = Array.isArray;
|
|
|
|
// node_modules/kojima/src/algebra/reader.js
|
|
var Reader = class _Reader extends Algebra(Monad) {
|
|
#run;
|
|
/** @param {InferredMorphism<T>} run */
|
|
constructor(run) {
|
|
super();
|
|
this.#run = run;
|
|
}
|
|
/**
|
|
* @template T
|
|
* @type {ApplicativeTypeRef<T, Reader<T>>['of']}
|
|
* @param {T} a
|
|
* @returns {Reader<T>}
|
|
*/
|
|
static of(a) {
|
|
return new _Reader(
|
|
/** @type {InferredMorphism<T>} */
|
|
(_env) => a
|
|
);
|
|
}
|
|
/** @template T */
|
|
static ask() {
|
|
return new _Reader(
|
|
/** @type {InferredMorphism<T>} */
|
|
id2
|
|
);
|
|
}
|
|
/**
|
|
* @type {Functor<T>['map']}
|
|
* @param {InferredMorphism<T>} f
|
|
* @returns {Reader<T>}
|
|
*/
|
|
map(f) {
|
|
return (
|
|
/** @type {Reader<any>} */
|
|
this.chain((value) => _Reader.of(f(value)))
|
|
);
|
|
}
|
|
/**
|
|
* @type {Chain<T>['chain']}
|
|
* @param {InferredMorphism<T>} f
|
|
* @returns {Reader<T>}
|
|
*/
|
|
chain(f) {
|
|
return new _Reader((env) => {
|
|
const result = this.#run(env);
|
|
const next2 = f(result);
|
|
return next2.run(env);
|
|
});
|
|
}
|
|
/**
|
|
* @template U
|
|
* @type {Apply<T>['ap']}
|
|
* @param {Reader<Morphism<T, U>>} b
|
|
* @returns {Reader<U>}
|
|
*/
|
|
ap(b) {
|
|
return (
|
|
/** @type {Reader<U>} */
|
|
b.chain(
|
|
(f) => (
|
|
/** @type {Reader<U>} */
|
|
this.map(f)
|
|
)
|
|
)
|
|
);
|
|
}
|
|
/**
|
|
* @param {InferredMorphism<T>} f
|
|
* @returns {Reader<T>}
|
|
*/
|
|
local(f) {
|
|
return new _Reader(
|
|
/** @type {InferredMorphism<T>} */
|
|
(env) => this.#run(f(env))
|
|
);
|
|
}
|
|
/**
|
|
* @template U
|
|
* @param {T} env
|
|
* @returns {U}
|
|
*/
|
|
run(env) {
|
|
return this.#run(env);
|
|
}
|
|
};
|
|
|
|
// node_modules/izuna/src/curry.js
|
|
function curryN2(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 curry2(func) {
|
|
return curryN2(func.length, func);
|
|
}
|
|
|
|
// node_modules/izuna/src/list.js
|
|
function isIterable2(value) {
|
|
return value[Symbol.iterator] != null;
|
|
}
|
|
function* iter2(value) {
|
|
if (isIterable2(value)) {
|
|
yield* Iterator.from(value);
|
|
} else {
|
|
yield value;
|
|
}
|
|
}
|
|
var concat2 = function* (...iterators) {
|
|
for (const iter3 of iterators) {
|
|
for (const item of Iterator.from(iter3)) {
|
|
yield item;
|
|
}
|
|
}
|
|
};
|
|
var prepend2 = curry2(
|
|
/**
|
|
* @template T
|
|
* @param {T} x
|
|
* @param {Iterable<T>} xs
|
|
*/
|
|
(x, xs) => concat2([x], xs)
|
|
);
|
|
|
|
// node_modules/izuna/src/function.js
|
|
var id3 = (x) => x;
|
|
var pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);
|
|
var compose2 = curry2(
|
|
/**
|
|
* @template T, U, V
|
|
* @param {Morphism<U, V>} f
|
|
* @param {Morphism<T, U>} g
|
|
* @param {T} x
|
|
* @returns V
|
|
*/
|
|
(f, g, x) => chain3(g, chain3(f, x))
|
|
);
|
|
var liftA2 = (a) => Array.isArray(a) ? a : [a];
|
|
var liftF2 = curry2((binary, x, y) => binary(x, y));
|
|
var ifElse2 = curry2(
|
|
/**
|
|
* @template T
|
|
* @param {Predicate<T>} pred
|
|
* @param {InferredMorphism<T>} pass
|
|
* @param {InferredMorphism<T>} fail
|
|
* @param {T} x
|
|
*/
|
|
(pred, pass, fail2, x) => pred(x) ? pass(x) : fail2(x)
|
|
);
|
|
var when2 = curry2(
|
|
/**
|
|
* @template T
|
|
* @param {Predicate<T>} pred
|
|
* @param {InferredMorphism<T>} pass
|
|
* @param {T} x
|
|
*/
|
|
(pred, pass, x) => ifElse2(pred, pass, id3, x)
|
|
);
|
|
var unless2 = curry2(
|
|
/**
|
|
* @template T
|
|
* @param {Predicate<T>} pred
|
|
* @param {InferredMorphism<T>} fail
|
|
* @param {T} x
|
|
*/
|
|
(pred, fail2, x) => ifElse2(pred, id3, fail2, x)
|
|
);
|
|
var ap2 = curry2(
|
|
/**
|
|
* @template A, B
|
|
* @template {Morphism<A, B>} Ap
|
|
* @param {Morphism<A, B>} f
|
|
* @param {{ ap: Ap } | Ap} a
|
|
*/
|
|
(f, a) => {
|
|
const fs = liftA2(dispatchF("ap", f));
|
|
const args = liftA2(a);
|
|
const xs = fs.reduce((acc, f2) => concat2(acc, iter2(map2(f2, args))), []);
|
|
return [...xs];
|
|
}
|
|
);
|
|
var chain3 = curry2(
|
|
function chain4(f, a) {
|
|
}
|
|
);
|
|
var map2 = curry2((f, a) => {
|
|
});
|
|
var reduce2 = curry2((f, acc, xs) => {
|
|
});
|
|
|
|
// node_modules/izuna/src/type.js
|
|
var is2 = curry2(
|
|
/**
|
|
* @template T
|
|
* @param {FunctionConstructor} ctr
|
|
* @param {T} x
|
|
*/
|
|
(ctr, x) => x.constructor === ctr
|
|
);
|
|
var isArray2 = Array.isArray;
|
|
|
|
// src/fn.js
|
|
var Tuple = (...values) => Object.freeze(values);
|
|
var clone = ([h, iter3]) => [h, iter3.clone()];
|
|
var succeed = (v, [x, y]) => ok(Tuple(x.concat(v), y));
|
|
var fail = (msg, state, e = void 0) => err(new ParseError(msg, state, e));
|
|
var next = (state) => state[1].next().value;
|
|
var diff = (a, b) => b.slice(-Math.max(0, b.length - a.length));
|
|
var join = curry2(
|
|
/**
|
|
* @param {string} delim
|
|
* @param {string[]} val
|
|
*/
|
|
(delim, val) => val.join(delim)
|
|
);
|
|
var mapStr = curry2(
|
|
/**
|
|
* @param {(...args: any[]) => any} fn
|
|
* @param {string} str
|
|
*/
|
|
(fn, str2) => Array.from(str2).map((v) => fn(v))
|
|
);
|
|
|
|
// src/seq.js
|
|
var take = (n) => (state) => {
|
|
let result = anyChar(state);
|
|
for (let i = n; i > 0; i--) {
|
|
if (result.isErr()) {
|
|
return result.chain((e) => fail(`"take(${n})" failed`, state, e));
|
|
}
|
|
result = result.chain(anyChar);
|
|
}
|
|
return result;
|
|
};
|
|
var seq = (...parsers) => (
|
|
/** @param {ParserState} state */
|
|
(state) => {
|
|
let acc = ok(state);
|
|
for (const parser of parsers) {
|
|
if (acc.isOk()) {
|
|
acc = acc.chain(parser);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
return acc;
|
|
}
|
|
);
|
|
var many = curry2((parser, state) => {
|
|
let result = ok(state);
|
|
while (true) {
|
|
const res = parser(clone(state));
|
|
if (res.isOk()) {
|
|
result = res;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
return result;
|
|
});
|
|
var many1 = (parser) => seq(parser, many(parser));
|
|
|
|
// src/cond.js
|
|
var maybe = curry2(
|
|
/**
|
|
* @param {(...args: any[]) => Result<ParserState, ParseError>} parser
|
|
* @param {ParserState} state
|
|
*/
|
|
(parser, state) => {
|
|
const result = parser(clone(state));
|
|
return result.isOk() ? result : succeed([], state);
|
|
}
|
|
);
|
|
var not = curry2((parser, state) => {
|
|
const result = parser(clone(state));
|
|
if (result.isOk()) {
|
|
return fail(`'not' parser failed for ${parser.name}`, state);
|
|
} else {
|
|
return succeed([], state);
|
|
}
|
|
});
|
|
var until = curry2((parser, state) => {
|
|
let result = ok(state);
|
|
while (result.isOk()) {
|
|
console.log(parser.name, state);
|
|
result = result.chain(pipe(clone, parser));
|
|
if (result.isOk()) {
|
|
break;
|
|
} else {
|
|
result = anyChar(state);
|
|
}
|
|
}
|
|
return result;
|
|
});
|
|
var skip = curry2((parser, state) => {
|
|
});
|
|
|
|
// src/combinator.js
|
|
var any = (...parsers) => (
|
|
/**
|
|
* @param {ParserState} state
|
|
*/
|
|
(state) => {
|
|
for (const parser of parsers) {
|
|
const result = parser(clone(state));
|
|
if (result.isOk()) {
|
|
return result;
|
|
}
|
|
}
|
|
return fail("no matching parsers", state);
|
|
}
|
|
);
|
|
var anyOf = curry2(
|
|
/**
|
|
* @param {string} str
|
|
* @param {ParserState} state
|
|
*/
|
|
(str2, state) => any(...mapStr(char, str2))(state)
|
|
);
|
|
var map3 = curry2(
|
|
/**
|
|
* @param {(...args: any[]) => any} fn
|
|
* @param {Parser} parser
|
|
* @param {ParserState} state
|
|
*/
|
|
(fn, parser, state) => {
|
|
return parser(state).chain((result) => {
|
|
try {
|
|
const parsed = fn(diff(state[0], result[0]));
|
|
const backtrack = Tuple(state[0], result[1]);
|
|
return succeed(parsed, backtrack);
|
|
} catch (e) {
|
|
return fail("failed to map", state, e);
|
|
}
|
|
});
|
|
}
|
|
);
|
|
var eof = (state) => {
|
|
return clone(state).next().done ? succeed([], state) : fail("not end of stream", state);
|
|
};
|
|
|
|
// src/state.js
|
|
var ParseError = class extends Error {
|
|
/**
|
|
* @param {string} message
|
|
* @param {ParserState} state
|
|
* @param {Error} [cause]
|
|
*/
|
|
constructor(message, state, cause) {
|
|
super(message, { cause });
|
|
this.state = state;
|
|
}
|
|
};
|
|
var State = (value) => Object.freeze([[], Iter.from(value)]);
|
|
var parse = curry2((parser, input) => parser(State(input)));
|
|
var parseAll = curry2((parser, input) => pipe(
|
|
State,
|
|
seq(
|
|
parser,
|
|
until(eof)
|
|
)
|
|
)(input));
|
|
|
|
// src/const.js
|
|
var LowerAlpha = "abcdefghijklmnopqrstuvwxyz";
|
|
var UpperAlpha = LowerAlpha.toUpperCase();
|
|
var Alpha = LowerAlpha + UpperAlpha;
|
|
var Digits = "1234567890";
|
|
var Alphanumeric = Alpha + Digits;
|
|
|
|
// src/char.js
|
|
var char = curry2(
|
|
/**
|
|
* @param {string} ch
|
|
* @param {ParserState} state
|
|
*/
|
|
(ch, state) => next(state) === ch ? succeed(ch, state) : fail(`could not parse ${ch} `, state)
|
|
);
|
|
var str = curry2(
|
|
/**
|
|
* @param {string} str
|
|
* @param {ParserState} state
|
|
*/
|
|
(str2, state) => map3(
|
|
join(""),
|
|
seq(...mapStr(char, str2))
|
|
)(state)
|
|
);
|
|
var anyChar = (state) => {
|
|
const ch = next(state);
|
|
return !!ch ? succeed(ch, state) : fail("end of input", state);
|
|
};
|
|
var digit = anyOf(Digits);
|
|
var lowerAlpha = anyOf(LowerAlpha);
|
|
var upperAlpha = anyOf(UpperAlpha);
|
|
var alpha = any(lowerAlpha, upperAlpha);
|
|
var alphanumeric = any(alpha, digit);
|
|
})();
|