| Name | # | Haskell | Ramda | Sanctuary | Signature |
|---|---|---|---|---|---|
| identity | I | id |
identity |
I |
a → a |
| constant | K | const |
always |
K |
a → b → a |
| apply | A | ($) |
call |
I¹ |
(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² |
(a → b → c) → (a → b) → a → c |
| chain | S_³ | (=<<)² |
chain² |
chain² |
(a → b → c) → (b → a) → b → c |
| converge | S2³ | apply2way, liftA2², liftM2² |
lift2² |
(b → c → d) → (a → b) → (a → c) → a → d |
|
| psi | P | on |
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.
³) I could not find a consistent name for these combinators, but they are common enough in the JavaScript ecosystem to justify their inclusion. I named them myself in order to refer to their implementation.
⁴) 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. The implementation found in combinators.js
is the strictly evaluated "Z" combinator, which needs the extra wrapper
around g (g) on the right hand side.
@JamieDixon: I came here wondering if the combinator I was about to write had a well-known name.
I guess not. But now I think
FooCombmay be stuck in my head!