Skip to content

Instantly share code, notes, and snippets.

@ElectricCoffee
Created July 7, 2022 11:40
Show Gist options
  • Select an option

  • Save ElectricCoffee/895e78355730fd88ab6671e5c20b6eea to your computer and use it in GitHub Desktop.

Select an option

Save ElectricCoffee/895e78355730fd88ab6671e5c20b6eea to your computer and use it in GitHub Desktop.
export class Fn {
/**
* Identiy function. Returns its own input
* @param a
* @returns
*/
static id = <A>(a: A) => a;
/**
* Takes two arguments and returns the first.
* Useful for when you need to discard data.
* @example
* ```
* const data = [1, 2, 3, 4, 5, 6, 7];
* // zero-out the data array
* data.map((x) => Fn.constant(0, x)); // [0, 0, 0, 0, 0, 0, 0]
* ```
* @param a
* @param _b
* @returns
*/
static constant = <A, B>(a: A, _b: B) => a;
/**
* Same as `Fn.constant`, but partially applied.
* Creates a function that ignores its input and returns a constant value.
* Useful for when you need to discard data
* @example
* ```
* const data = [1, 2, 3, 4, 5, 6, 7];
* const nil = Fn.constant_(0);
* // zero-out the data array
* data.map(nil); // [0, 0, 0, 0, 0, 0, 0]
* ```
* @param a
* @param _b
* @returns
*/
static constant_ =
<A, B>(a: A) =>
(_b: B) =>
a;
/**
* Creates a new version of the input function with its arguments flipped
* @param f binary function
* @returns
*/
static flip_ =
<A, B, C>(f: (a: A, b: B) => C) =>
(b: B, a: A) =>
f(a, b);
/**
* Takes two functions f and g and two variables, applies g to x and y, and then takes the result of that and applies to f
* @example
* ```
* const eq = (a, b) => a === b;
* const lc = (a) => a.toLowerCase();
* // compares equality by first converting to lower case
* Fn.on(eq, lc, "foo", "FOO") ? "equal" : "unequal";
* ```
* @param f binary function
* @param g unary function
* @param x first argument
* @param y second argument
* @returns
*/
static on = <A, B, C>(f: (b1: B, b2: B) => C, g: (a: A) => B, x: A, y: A) =>
f(g(x), g(y));
/**
* Same as `Fn.on`, except partially applied
* @example
* ```
* const eq = (a, b) => a === b;
* const lc = (a) => a.toLowerCase();
* // compares equality by first converting to lower case
* const eqLc = Fn.on_(eq, lc);
* eqLc("foo", "FOO") ? "equal" : "unequal";
* ```
* @param f
* @param g
* @returns
*/
static on_ =
<A, B, C>(f: (b1: B, b2: B) => C, g: (a: A) => B) =>
(x: A, y: A) =>
f(g(x), g(y));
/**
* Takes functions `f`, `g`, and `h`, and a variable `a`, applies `a` to `g` and `h`, and sends the result into `f`
* @example
* ```
* const count = (xs) => xs.length;
* const sum = (xs) => xs.reduce((a, b) => a + b);
* const div = (a, b) => a / b;
* // calculates the average by dividing
* // the sum of the array by the number of elements in it
* Fn.fork(div, sum, count, [1, 2, 3, 4]);
* ```
* @param f binary function
* @param g unary function
* @param h unary function
* @param a input
* @returns
*/
static fork = <A, B, C, D>(
f: (b: B, c: C) => D,
g: (a: A) => B,
h: (a: A) => C,
a: A
) => f(g(a), h(a));
/**
* Same as `Fn.fork`, except partially applied.
* Takes functions `f`, `g`, and `h`, and a variable `a`, applies `a` to `g` and `h`, and sends the result into `f`
* @example
* ```
* const count = (xs) => xs.length;
* const sum = (xs) => xs.reduce((a, b) => a + b);
* const div = (a, b) => a / b;
* // calculates the average by dividing
* // the sum of the array by the number of elements in it
* const avg = Fn.fork_(div, sum, count);
* avg([1, 2, 3, 4])
* ```
* @param f binary function
* @param g unary function
* @param h unary function
* @param a input
* @returns
*/
static fork_ =
<A, B, C, D>(f: (b: B, c: C) => D, g: (a: A) => B, h: (a: A) => C) =>
(a: A) =>
f(g(a), h(a));
/**
* Same as `Fn.fork` except it takes two arguments instead of one.
* @param f binary function
* @param g unary function
* @param h unary function
* @param a first input
* @param b second input
* @returns
*/
static fork2 = <A, B, C, D, E>(
f: (b: C, c: D) => E,
g: (a: A) => C,
h: (a: B) => D,
a: A,
b: B
) => f(g(a), h(b));
/**
* Same as `Fn.fork_`, except the resulting function takes two inputs
* @param f binary function
* @param g unary function
* @param h unary function
* @param a first input
* @param b second input
* @returns
*/
static fork2_ =
<A, B, C, D, E>(f: (b: C, c: D) => E, g: (a: A) => C, h: (a: B) => D) =>
(a: A, b: B) =>
f(g(a), h(b));
/**
* Applies the same argument to a function twice
* @param f
* @param x
* @returns
*/
static reflex = <A, B>(f: (a1: A, a2: A) => B, x: A) => f(x, x);
/**
* same as `Fn.reflex`, except partially applied
* @param f
* @returns
*/
static reflex_ =
<A, B>(f: (a1: A, a2: A) => B) =>
(x: A) =>
f(x, x);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment