Download the PHP package loophp/combinator without Composer
On this page you can find all versions of the php package loophp/combinator. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download loophp/combinator
More information about loophp/combinator
Files in loophp/combinator
Informations about the package combinator
![Latest Stable Version][latest stable version] ![GitHub stars][github stars] ![Total Downloads][total downloads] ![GitHub Workflow Status][github workflow status] ![Scrutinizer code quality][code quality] ![Type Coverage][type coverage] ![Code Coverage][code coverage] ![License][license] ![Donate!][donate github]
Combinator
This package provides a comprehensive collection of well-known combinators for PHP, enabling a more declarative, point-free programming style.
Description
A combinator is a higher-order function that uses only function application and previously defined combinators to define a result from its arguments. This concept was introduced by Moses Schönfinkel in 1920 and later developed by Haskell Curry.
In computer science, combinatory logic serves as a theoretical model of computation and is a cornerstone of functional programming language design. The core idea is to build complex functions without ever having to mention variables.
Why use Combinators?
Using combinators can help you:
- Write cleaner, more declarative code: By abstracting away function composition and argument manipulation, your code can become more readable and expressive.
- Avoid temporary variables: Combinators provide powerful ways to pipe data through a series of functions in a clean, fluent manner.
- Explore functional programming: This library provides a practical way to learn about and experiment with fundamental concepts of functional programming and lambda calculus, right within PHP.
Requirements
- PHP >= 8.0
Installation
You can install the package via Composer:
Available Combinators
The following is a list of the combinators available in this package.
| Name | Alias | Haskell | Lambda Calculus | Term Definition (JS-like) | Type |
|---|---|---|---|---|---|
| A | Applicator | $ |
λab.ab |
a => b => a(b) |
(a -> b) -> a -> b |
| B | Bluebird | . |
λabc.a(bc) |
a => b => c => a(b(c)) |
(b -> c) -> (a -> b) -> a -> c |
| B₁ | Blackbird | ... |
λabcd.a(bcd) |
a => b => c => d => a(b(c)(d)) |
(c -> d) -> (a -> b -> c) -> a -> b -> d |
| C | Cardinal | flip |
λabc.acb |
a => b => c => a(c)(b) |
(a -> b -> c) -> b -> a -> c |
| D | Dove | λabcd.ab(cd) |
a => b => c => d => a(b)(c(d)) |
(b -> c -> d) -> b -> (a -> c) -> a -> d |
|
| E | Eagle | λabcde.ab(cde) |
a => b => c => d => e => a(b)(c(d)(e)) |
(a -> d -> e) -> a -> (b -> c -> d) -> b -> c -> e |
|
| F | Finch | λabc.cba |
a => b => c => c(b)(a) |
a -> b -> (b -> a -> c) -> c |
|
| G | Goldfinch | λabcd.ad(bc) |
a => b => c => d => a(d)(b(c)) |
(a -> b -> c) -> (d -> b) -> d -> a -> c |
|
| H | Hummingbird | λabc.abcb |
a => b => c => a(b)(c)(b) |
(a -> b -> a -> c) -> a -> b -> c |
|
| I | Identity (Idiot) | id |
λa.a |
a => a |
a -> a |
| J | Jay | λabcd.ab(adc) |
a => b => c => d => a(b)(a(d)(c)) |
(a -> b -> b) -> a -> b -> a -> b |
|
| K | Kestrel | const |
λab.a |
a => b => a |
a -> b -> a |
| Ki | Kite | flip const |
λab.b |
a => b => b |
a -> b -> b |
| L | Lark | λab.a(bb) |
a => b => a(b(b)) |
* |
|
| M | Mockingbird | λa.aa |
a => a(a) |
* |
|
| O | Owl | λab.b(ab) |
a => b => b(a(b)) |
((a -> b) -> a) -> (a -> b) -> b |
|
| Omega | Ω | λa.(aa)(aa) |
a => (a(a))(a(a)) |
* |
|
| Φ | Phoenix | λabcd.a(bd)(cd) |
a => b => c => d => a(b(d))(c(d)) |
(b -> c -> d) -> (a -> b) -> (a -> c) -> a -> d |
|
| Ψ | Psi | on |
λabcd.a(bc)(bd) |
a => b => c => d => a(b(c))(b(d)) |
(b -> b -> c) -> (a -> b) -> a -> a -> c |
| Q | Queer | flip (.) |
λabc.b(ac) |
a => b => c => b(a(c)) |
(a -> b) -> (b -> c) -> a -> c |
| R | Robin | λabc.bca |
a => b => c => b(c)(a) |
a -> (b -> a -> c) -> b -> c |
|
| S | Starling | <*> |
λabc.ac(bc) |
a => b => c => a(c)(b(c)) |
(a -> b -> c) -> (a -> b) -> a -> c |
| S' | S Prime | λabc.a(bc)c |
a => b => c => a(b(c))(c) |
(b -> a -> c) -> (a -> b) -> a -> c |
|
| S₂ | S-Two | liftA2 |
λabcd.a(bd)(cd) |
a => b => c => d => a(b(d))(c(d)) |
(b -> c -> d) -> (a -> b) -> (a -> c) -> a -> d |
| T | Thrush | (&) |
λab.ba |
a => b => b(a) |
a -> (a -> b) -> b |
| U | Turing | λab.b(aab) |
a => b => b(a(a)(b)) |
((a -> b) -> b) -> (a -> b) -> b |
|
| V | Vireo | λabc.cab |
a => b => c => c(a)(b) |
a -> b -> (a -> b -> c) -> c |
|
| W | Warbler | λab.abb |
a => b => a(b)(b) |
(a -> a -> b) -> a -> b |
|
| Y | Y-Fixed point | fix |
λf.(λx.f(xx))(λx.f(xx)) |
f => (x => f(x(x)))(x => f(x(x))) |
(a -> a) -> a |
| Z | Z-Fixed point | fix |
λf.(λx.f(λv.xxv))(λx.f(λv.xxv)) |
f => (x => f(v => x(x)(v)))(x => f(v => x(x)(v))) |
(a -> a) -> a |
*indicates a combinator that is not simply typed because it relies on self-application.
Combinator by Example
Click on any combinator below to see a practical usage example. All combinators
are invokable classes, but the easiest way to access them is through the
loophp\combinator\Combinators facade, which statically provides each one.
A (Applicator) Combinator
- **Lambda:** `λab.ab` - **Purpose:** Applies a function `a` to an argument `b`. In Haskell, this is the `$` operator. It can help reduce the number of parentheses in complex expressions.B (Bluebird) Combinator
- **Lambda:** `λabc.a(bc)` - **Purpose:** Function composition. It takes two functions, `a` and `b`, and a value `c`, and applies `a` to the result of `b` applied to `c`. This is `.` in Haskell.B₁ (Blackbird) Combinator
- **Lambda:** `λabcd.a(bcd)` - **Purpose:** Extended function composition for three functions: `a(b(c(d)))`.C (Cardinal) Combinator
- **Lambda:** `λabc.acb` - **Purpose:** Flips arguments. It takes a function `a` and two arguments `b` and `c`, and applies `a` with `c` as the first argument and `b` as the second. This is `flip` in Haskell.D (Dove) Combinator
- **Lambda:** `λabcd.ab(cd)` - **Purpose:** Composes two functions and their arguments: `a(b)(c(d))`.E (Eagle) Combinator
- **Lambda:** `λabcde.ab(cde)` - **Purpose:** Five-argument composition, useful for deeply nested function calls: `a(b)(c(d(e)))`.F (Finch) Combinator
- **Lambda:** `λabc.cba` - **Purpose:** Reverses the application order. Applies `c` to `b`, and then to `a`.G (Goldfinch) Combinator
- **Lambda:** `λabcd.ad(bc)` - **Purpose:** Applies arguments in a unique order: `a(d)(b(c))`.H (Hummingbird) Combinator
- **Lambda:** `λabc.abcb` - **Purpose:** Applies a three-argument function, but uses the second argument twice: `a(b)(c)(b)`.I (Identity / Idiot) Combinator
- **Lambda:** `λa.a` - **Purpose:** The identity function. It returns whatever argument it receives. This is `id` in Haskell.J (Jay) Combinator
- **Lambda:** `λabcd.ab(adc)` - **Purpose:** A complex combinator useful for specific recursive or state-passing scenarios: `a(b)(a(d)(c))`.K (Kestrel) Combinator
- **Lambda:** `λab.a` - **Purpose:** The constant function. It takes two arguments and always returns the first. This is `const` in Haskell.Ki (Kite) Combinator
- **Lambda:** `λab.b` - **Purpose:** The opposite of the Kestrel. It takes two arguments and always returns the second.L (Lark) Combinator
- **Lambda:** `λab.a(bb)` - **Purpose:** Applies function `a` to the result of function `b` applied to itself. This requires `b` to be a function that can meaningfully accept itself as an argument.M (Mockingbird) Combinator
- **Lambda:** `λa.aa` - **Purpose:** Self-application (also known as the `ω` combinator). It applies its single argument (which must be a function) to itself.O (Owl) Combinator
- **Lambda:** `λab.b(ab)` - **Purpose:** A peculiar form of composition, `b(a(b))`. Useful in specific recursive algorithms or data structure manipulations.Omega (Ω) Combinator
- **Lambda:** `λa.(aa)(aa)` - **Purpose:** The divergent combinator. It is constructed from the Mockingbird (`M`) as `MM`. When applied to _any_ function, it creates an infinitely recursive call that will exhaust memory. **Do not run this code.**Φ (Phoenix) Combinator
- **Lambda:** `λabcd.a(bd)(cd)` - **Purpose:** Distributes an argument `d` across two functions `b` and `c`, then combines the results with function `a`.Ψ (Psi) Combinator
- **Lambda:** `λabcd.a(bc)(bd)` - **Purpose:** Another distribution combinator, but this one distributes a function `b` over two arguments `c` and `d`.Q (Queer) Combinator
- **Lambda:** `λabc.b(ac)` - **Purpose:** A different form of composition, applying `b` to the result of `a` applied to `c`.R (Robin) Combinator
- **Lambda:** `λabc.bca` - **Purpose:** Reorders arguments for a two-argument function `b`.S (Starling) Combinator
- **Lambda:** `λabc.ac(bc)` - **Purpose:** The substitution combinator. It applies a third argument `c` to both `a` and `b`, then applies the result of `a(c)` to the result of `b(c)`. It is fundamental to combinatory logic.S' (S Prime) Combinator
- **Lambda:** `λabc.a(bc)c` - **Purpose:** A variation of the Starling that provides the final argument `c` to the outer function `a` as well. Useful for functions that need both the result of an operation and the original value, such as logging or debugging.S₂ (S-Two) Combinator
- **Lambda:** `λabcd.a(bd)(cd)` - **Purpose:** Applies two different functions `b` and `c` to the same data `d`, and then combines their results with a third function `a`. In Haskell, this is similar to `liftA2`.T (Thrush) Combinator
- **Lambda:** `λab.ba` - **Purpose:** Reverse application. Applies function `b` to argument `a`. This is `(&)` in Haskell and is useful for data-last programming styles.U (Turing) Combinator
- **Lambda:** `λab.b(aab)` - **Purpose:** A fixed-point combinator. `U(f)(g) = g(f(f)(g))`. In strict (eager) PHP, recursion requires the step function to call `$self($self)` explicitly and a seed callable (here: `I`) as the second argument.V (Vireo) Combinator
- **Lambda:** `λabc.cab` - **Purpose:** Argument swapping. Given `c`, `a`, `b`, it calls `c(a)(b)`.W (Warbler) Combinator
- **Lambda:** `λab.abb` - **Purpose:** Duplicates an argument. It applies function `a` to argument `b` twice.Y (Y-Fixed point) Combinator
- **Lambda:** `λf.(λx.f(xx))(λx.f(xx))` - **Purpose:** Creates a recursive function from a generator function without naming the recursive function directly.Z (Z-Fixed point) Combinator
- **Lambda:** `λf.(λx.f(λv.xxv))(λx.f(λv.xxv))` - **Purpose:** Creates a recursive function from a generator function using an eta-expanded recursive callback, which is suitable for strict evaluation.Suggested reading and resources
- To Mock a Mockingbird
- http://dkeenan.com/Lambda/
- https://gist.github.com/Avaq/1f0636ec5c8d6aed2e45
- https://en.wikipedia.org/wiki/Combinatory_logic
- https://joshmoody.org/blog/programming-with-less-than-nothing/
- https://github.com/joshmoody24/skoobert
Contributing
Feel free to contribute by sending pull requests. We are a usually very responsive team and we will help you going through your pull request from the beginning to the end.
For some reasons, if you can't contribute to the code and willing to help, sponsoring is a good, sound and safe way to show us some gratitude for the hours we invested in this package.
Sponsor me on Github and/or any of the contributors.
Thanks
Authors
Changelog
See CHANGELOG.md for a changelog based on git commits. For more detailed changelogs, please check the release changelogs.
[latest stable version]: https://img.shields.io/packagist/v/loophp/combinator.svg?style=flat-square [github stars]: https://img.shields.io/github/stars/loophp/combinator.svg?style=flat-square [total downloads]: https://img.shields.io/packagist/dt/loophp/combinator.svg?style=flat-square [github workflow status]: https://img.shields.io/github/actions/workflow/status/loophp/combinator/tests.yml?branch=master&style=flat-square [code quality]: https://img.shields.io/scrutinizer/quality/g/loophp/combinator/master.svg?style=flat-square [type coverage]: https://img.shields.io/badge/dynamic/json?style=flat-square&color=color&label=Type%20coverage&query=message&url=https%3A%2F%2Fshepherd.dev%2Fgithub%2Floophp%2Fcombinator%2Fcoverage [code coverage]: https://img.shields.io/scrutinizer/coverage/g/loophp/combinator/master.svg?style=flat-square [license]: https://img.shields.io/packagist/l/loophp/combinator.svg?style=flat-square [donate github]: https://img.shields.io/badge/Sponsor-Github-brightgreen.svg?style=flat-square [donate paypal]: https://img.shields.io/badge/Sponsor-Paypal-brightgreen.svg?style=flat-square