import { Either } from "./either"; import { Option } from "./option"; const ArrayInstanceOf = [ Array, Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array ]; export type Monoid = Either | Option | Promise | Set | Array | ArrayLike | Map | { [key: string]: A } | Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array; export const Identity = (a: any) => a; export type Functor = (f: (a: A) => B) => (m: Monoid) => Monoid; export function fmap (getter: (g: Monoid) => A, setter: (s: B) => Monoid, err: (e: Error) => Monoid ): Functor { return (func: (a: A) => B) => (m: Monoid): Monoid => { try { let val: any = getter(m); if (typeof val === "object" && ArrayInstanceOf.some(i => val instanceof i)) { val = val.map(func); } return setter(func(val)); } catch (e) { return err(e); } }; }; export function compose (f: (a: A) => B) { const funcIterator: Function[] = []; function _compose (f2?: (a: C) => D): ((b: D) => E) | ((a: A) => D) { if (f2 === undefined) { return (a: A): D => { let val: any = a; for (let i in funcIterator) { val = funcIterator[i](val); } return val; }; } funcIterator.push(f2); return _compose.bind(this); }; return _compose.call(this, f); } function filter (f: (f: T) => boolean): (arr: T[]) => T[] { return (arr: T[]) => Array.prototype.filter.call(arr, f); } function sum (arr: number[]): number { return arr.reduce((p, c) => p + c, 0); } function minus (arr: number[]): number { return arr.reduce((p, c) => p - c, 0); }