j45l/functional-php

Functional primitives for PHP

Maintainers

Package info

github.com/jordibisbal/functional-php

pkg:composer/j45l/functional-php

Statistics

Installs: 20 363

Dependents: 4

Suggesters: 0

Stars: 4

Open Issues: 0

3.0.21 2024-02-07 03:01 UTC

README

Functional primitives for PHP 8.2+, inspired by several functional libraries such as lstrojny/functional-php, Typelevel Cats, Scala, SML, etc.

This library provides a small, opinionated toolbox to write PHP in a functional style: working with collections as first-class values, composing behaviour out of small functions, and keeping side effects contained.

What you get

Collection filtering and selection

Pick elements out of any iterable without hand-rolling loops: first / last / head / tail, butLast, take, pluck, select / reject, best / worst, and traverse for matching against nested tree-like data.

Collection transformation

Reshape and combine collections: map, flatMap, reindex, fold / foldRight, reduce / reduceRight, sum, merge / mergeGenerator, zip / unzip, concat, cartesianProduct, crossCompareSet, from / upTo, recurseTimes, and conversions between iterables, arrays and generators (toArray, toGenerator, toIterable, yieldIterable, unindex).

Function composition, partial application and currying

Build new functions out of existing ones: compose, pipe, partial, partialRight.

Logic and predicate helpers

Combine and negate predicates and ask boolean questions of collections: every, some, none, not.

Value functions

Tiny building blocks that show up everywhere when composing: identity, nop, trueFn, falseFn, value, with.

Object & type functions

Work with values whose type or shape needs checking or adjusting: isAOr, isClosureOr, cloneWith (clones an object and runs a closure bound to it, so even private properties can be set on the copy).

Loop and effect functions

Express imperative-shaped work without leaving the functional style: doWhile, doUntil, doEach, also (run a side effect and pass the value through), delay, tryOrThrow.

Optimization

tailRecursion decorates a recursive closure with a trampoline so deep recursion does not blow the PHP stack, and MemoizeTrait caches results of pure methods.

Sequences

Lazy numeric sequences as iterable objects: LinearSequence, ExponentialSequence, FibonacciSequence, plus the underlying Sequence / SequenceIterator to roll your own.

Tuples

Simple immutable Pair and Triplet value objects, with factory helpers — useful as return types for functions that naturally produce two or three related values (and as the output of crossCompareSet).

PHPUnit helpers

A handful of assertion helpers in PHPUnitFunctions.php for testing code written in this style.

Design notes

  • The library targets PHP 8.2+.
  • Most functions accept any iterable as input and return an array. Some fully consume generators — beware of infinite ones.
  • Only \Closure is accepted where a function is expected (not the looser callable). Wrap anything else in an arrow function, e.g. fn(...$a) => strtolower(...$a).

Install

composer require j45l/functional-php

Documentation

Per-function reference with signatures and examples: Functions.

For anything not covered there, the unit tests under tests/ are the source of truth.