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-point4 | 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.
4) 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.
Hey all,
I love this list and come back to it regularly.
I recently wrote a combinator and I'm trying to find out the name of it. I'll do my best to describe it here and perhaps someone who's knowledgeable in these things will know what it's called.
The function signature I've identified is:
(a -> b -> c) -> (a -> c -> d) -> (a -> b -> d)
which is a function that takes 2 binary functions. When a value is applied to the resulting function, that value is applied to both of the binary functions. When the next value is applied it is then applied to the second function in the composition, the result of which is applied to the first function in the composition.It's a little bit like
substitution
but for 2 binary functions instead of 1 unary and 1 binary.My implementation of this (using Crocks) looks like:
const fooComb = converge(binary(compose));
Thanks again for maintaining this excellent list and I hope my explanation above is expressed clearly enough.