@fpjs/overture
Version:
A Javascript prelude
118 lines (99 loc) • 3.3 kB
JavaScript
// 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;
}
};