{{ message }}

Instantly share code, notes, and snippets.

# brendanberg/combinators.js

Forked from Avaq/combinators.js
Created Dec 28, 2018
Common combinators in JavaScript
 const I = x => x; const K = x => y => x; const A = f => x => f(x); const T = x => f => f(x); const W = f => x => f(x)(x); const C = f => y => x => f(x)(y); const B = f => g => x => f(g(x)); const S = f => g => x => f(x)(g(x)); const P = f => g => x => y => f(g(x))(g(y)); const Y = f => (g => g(g))(g => f(x => g(g)(x)));
Name # Haskell Ramda Sanctuary Signature
identity I `id` `identity` `I` `a → a`
constant K `const` `always` `K` `a → b → a`
apply¹ A `(\$)` `call` `(a → b) → a → b`
thrush T `(&)` `applyTo` `T` `a → (a → b) → b`
duplication W `join`² `unnest`² `join`² `(a → a → b) → a → b`
flip C `flip` `flip` `flip` `(a → b → c) → b → a → c`
compose B `(.)`, `fmap`² `map`² `compose`, `map`² `(b → c) → (a → b) → a → c`
substitution S `ap`² `ap`² `ap`² `(a → b → c) → (a → b) → a → c`
psi P `on` `on` `(b → b → c) → (a → b) → a → a → c`
fix-point³ Y `fix` `(a → a) → a`

¹) The A-combinator can be implemented as an alias of the I-combinator. Its implementation in Haskell exists because the infix nature gives it some utility. Its implementation in Ramda exists because it is overloaded with additional functionality.

²) Algebras like `ap` have different implementations for different types. They work like Function combinators only for Function inputs.

³) In JavaScript and other non-lazy languages, it is impossible to implement the Y-combinator. Instead a variant known as the applicative or strict fix-point combinator is implemented. This variant is sometimes rererred to as the Z-combinator.

Note that when I use the word "combinator" in this context, it implies "function combinator in the untyped lambda calculus".