UNPKG

@fpjs/overture

Version:
118 lines (99 loc) 3.3 kB
// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. import {compose, constant} from "@fpjs/overture/base"; import {pure, lift2} from "@fpjs/overture/algebras/applicative"; import {map} from "@fpjs/overture/algebras/functor"; import {concat} from "@fpjs/overture/algebras/semigroup"; import {equals} from "@fpjs/overture/algebras/setoid"; function Array$equals(other) { if (this === other) return true; if (other == null) return false; if (this.length !== other.length) return false; for (let i = 0; i < this.length; i++) { if (!equals (this[i]) (other[i])) return false; } return true; } function Array$concat(other) { return this.concat(other); } function Array$map(f) { return this.map ((x) => f (x)); } function Array$ap(fs) { if (this.length === 0 || fs.length === 0) { return []; } let ys = new Array(this.length * fs.length - 1); let k = 0; for (let i = 0; i < fs.length; i++) { for (let j = 0; j < this.length; j++) { ys[k++] = fs[i] (this[j]); } } return ys; } function Array$chain(f) { let ys = []; for (let i = 0; i < this.length; i++) { for (let j = 0, xs = f (this[i]); j < xs.length; j++) { ys.push(xs[j]); } } return ys; } function Array$reduce(f, z) { let acc = z; for (let i = 0; i < this.length; i++) { acc = f (acc, this[i]); } return acc; } function Array$traverse(typeRep, f) { const pair = (x) => (y) => [x, y]; const go = (idx, n) => { switch (n) { case 0: return pure (typeRep) ([]); case 2: return lift2 (pair) (f (this[idx])) (f (this[idx+1])); default: const m = Math.floor(n / 4) * 2; return lift2 (concat) (go (idx, m)) (go (idx+m, n-m)); } }; return this.length % 2 === 1 ? lift2 (concat) (map (pure (Array)) (f (this[0]))) (go (1, this.length - 1)) : go(0, this.length); } function Function$map(f) { return compose (f) (this); } function Promise$map(f) { return this.then ((x) => f (x)); } function Promise$ap(a) { return this.then ((x) => a.then((f) => f(x))); } /** * Install support for Overture types (e.g. Setoid, Functor) on builtin types, * such as Array. */ export const patchBuiltins = () => { Array['fantasy-land/empty'] = constant([]); Array['fantasy-land/of'] = (x) => [x]; Array.prototype['fantasy-land/equals'] = Array$equals; Array.prototype['fantasy-land/concat'] = Array$concat; Array.prototype['fantasy-land/map'] = Array$map; Array.prototype['fantasy-land/ap'] = Array$ap; Array.prototype['fantasy-land/chain'] = Array$chain; Array.prototype['fantasy-land/reduce'] = Array$reduce; Array.prototype['fantasy-land/traverse'] = Array$traverse; Function.prototype['fantasy-land/map'] = Function$map; if (typeof (Promise) !== 'undefined') { Promise['fantasy-land/of'] = (x) => Promise.resolve(x); Promise.prototype['fantasy-land/map'] = Promise$map; Promise.prototype['fantasy-land/ap'] = Promise$ap; } };