UNPKG

mezzanine

Version:

Fantasy land union types with pattern matching

138 lines (120 loc) 2.72 kB
//@flow /** * id :: a -> a * * * @template A * @param {A} a * @returns {A} */ export function id<A>(a: A) { return a } /** * compose :: (b -> c) -> (a -> b) -> (a -> c) * * @template A * @template B * @template C * @param {function(B): C} f * @param {function(A): B} g * @returns {function(A): C} */ export function compose<A, B, C>(f: (B) => C, g: (A) => B): (A) => C { return function(x: A) { return f(g(x)) } } /** * apply :: (a -> b) -> a -> b * * @template A * @template B * @param {function(A): B} f * @param {A} x * @returns {B} */ function apply<A, B>(f: (A) => B, x: A): B { return f(x) } interface CurriedFunction2<A, B, C> { (): CurriedFunction2<A, B, C>, (A): (B) => C, (A, B): C } interface CurriedFunction3<A, B, C, D> { (): CurriedFunction3<A, B, C, D>, (A): CurriedFunction2<B, C, D>, (A, B): (C) => D, (A, B, C): D } interface CurriedFunction4<A, B, C, D, E> { (): CurriedFunction4<A, B, C, D, E>, (A): CurriedFunction3<B, C, D, E>, (A, B): CurriedFunction2<C, D, E>, (A, B, C): (D) => E, (A, B, C, D): E } /** * curry2 :: ((a, b) -> c) -> (a -> b -> c) * * @template A * @template B * @template C * @param {function(A, B): C} f * @returns {CurriedFunction2<A, B, C>} */ export function curry2<A, B, C>(f: (A, B) => C): CurriedFunction2<A, B, C> { function curried(a, b) { switch (arguments.length) { case 0: return curried case 1: return b => f(a, b) default: return f(a, b) } } return curried } /** * curry3 :: ((a, b, c) -> d) -> (a -> b -> c -> d) * * @template A * @template B * @template C * @template D * @param {function(A, B, C): D} f * @returns {CurriedFunction3<A, B, C, D>} */ export function curry3<A, B, C, D>(f: (A, B, C) => D): CurriedFunction3<A, B, C, D> { function curried(a, b, c) { // eslint-disable-line complexity switch (arguments.length) { case 0: return curried case 1: return curry2((b, c) => f(a, b, c)) case 2: return c => f(a, b, c) default:return f(a, b, c) } } return curried } /** * curry4 :: ((a, b, c, d) -> e) -> (a -> b -> c -> d -> e) * * @template A * @template B * @template C * @template D * @template E * @param {function(A, B, C, D): E} f * @returns {CurriedFunction4<A, B, C, D, E>} */ export function curry4<A, B, C, D, E>(f: (A, B, C, D) => E): CurriedFunction4<A, B, C, D, E> { function curried(a, b, c, d) { switch (arguments.length) { case 0: return curried case 1: return curry3((b, c, d) => f(a, b, c, d)) case 2: return curry2((c, d) => f(a, b, c, d)) case 3: return d => f(a, b, c, d) default:return f(a, b, c, d) } } return curried }