# typescript/functional [![Build Status](https://thunderk.visualstudio.com/typescript/_apis/build/status/functional?branchName=master)](https://dev.azure.com/thunderk/typescript/_build?pipelineNameFilter=functional) ## About Provides some common helpers for functional-style programming. ## Import In deno: ```typescript import { bool } from "https://js.thunderk.net/functional/mod.ts"; ``` In browser: ```html ``` ## Use **always** and **never** return true and false respectively ```typescript always(); // => true never(); // => false ``` **and**, **or** and **not** allow to combine or negate predicates ```typescript const a = and((x: number) => x > 2, (x: number) => x < 5); a(2); // => false a(3); // => true a(4); // => true a(5); // => false const o = or((x: number) => x < 2, (x: number) => x > 3); o(1); // => true o(2); // => false o(3); // => false o(4); // => true const n = not((x: number) => x == 1); n(0); // => true n(1); // => false n(2); // => true ``` **at** gets an array's item by position: ```typescript const getthird = at(2); getthird([2, 4, 8, 16]); // => 8 getthird([2, 4]); // => undefined const getsecondlast = at(-2); getsecondlast([1, 2, 3, 4]); // => 3 getsecondlast([1]); // => undefined ``` **attr** gets an object's attribute: ```typescript const getx = attr("x"); getx({ x: 3 }); // => 3 ``` **bool** checks for boolean equivalence (in a broader sense than !(!(val))): ```typescript bool(undefined); // => false bool(null); // => false bool(-1); // => true bool(0); // => false bool(1); // => true bool(""); // => false bool(" "); // => true bool("abc"); // => true bool([]); // => false bool([1, 2, 3]); // => true bool({}); // => false bool({ x: 1 }); // => true ``` **cmp** simplifies the use of array sorting: ```typescript [8, 3, 5].sort(cmp()) // => [3, 5, 8] [8, 3, 5].sort(cmp({ reverse: true })) // => [8, 5, 3] [-2, 8, -7].sort(cmp({ key: Math.abs })); // => [-2, -7, 8] ``` **defined** removes undefined values from an object: ```typescript defined({ a: 1, b: undefined }); // => {a: 1} ``` **first** and **last** return the first or last item of an array: ```typescript first([1, 2, 3]); // => 1 first([]); // => undefined last([1, 2, 3]); // => 3 last([]); // => undefined ``` **identity** returns its argument untouched: ```typescript a === identity(a); // => true ``` **is** and **isinstance** checks for strict equality and inheritance: ```typescript const f = is(8); f(8); // => true f(5 + 3); // => true f("8"); // => false f(null); // => false class A {} class A1 extends A {} class A2 extends A {} class B {} const f: any[] = [5, null, undefined, new A(), new A1(), new B(), new A2()]; const result: A[] = f.filter(isinstance(A)); // => [f[3], f[4], f[6]] ``` **nn**, **nu** and **nnu** checks at run-time for null or undefined: ```typescript nn(undefined); // => undefined nn(null); // => Error nn(1); // => 1 nu(undefined); // => Error nu(null); // => null nu(1); // => 1 nnu(undefined); // => Error nnu(null); // => Error nnu(1); // => 1 ``` **nop** does nothing (useful for some callbacks): ```typescript new ConstructorWithMandatoryCallback(nop); ``` **options** merges options over default values: ```typescript options({ a: 1, b: 2, c: 3, d: 4 }, { a: 11, c: 33 }, { b: 22 }); // => {a: 11, b: 22, c: 33, d: 4} ``` **partial** applies a partial configuration object as first argument of compatible functions: ```typescript const sum = (args: { a: number; b: number }) => args.a + args.b; const plus1 = partial({ a: 1 }, sum); plus1({ b: 8 }); // => 9 ``` **pipe** chains two functions as one: ```typescript const f = pipe((x: number) => x * 2, (x: number) => x + 1); f(3); // => 7 ((3 * 2) + 1) ```