Examples
Worked examples that go beyond single-function docs — each one starts with a real scenario, builds the solution step by step, and explains which pieces of the library do what and why.
-
Audit trails with tap / sideEffect
— Add logging, audit records, or debug output to a pipeline without breaking the data flow. `sideEffect` runs a callable for its effect and passes the value through unchanged — drop it anywhere in a compose or pipe.
-
Transforming complex objects
— Take a list of raw API records, derive a fresh view model for each — with computed fields, nested lookups, and conditional logic — using recordEncoder, encodeProperty, pluckProperty and compose. No foreach loops, no temporary variables.
-
Config-driven pipelines
— Build a pipeline from a list of function names loaded at runtime — from config, from a database, from user choices. Because compose takes an array of callables, "define your pipeline in YAML" is a one-line implementation.
-
Currency and pricing pipelines
— Build a reusable "money" pipeline — convert currencies, apply tax, round, format — and use the same composed function across cart totals, invoices, and reports. Changing the rules is one edit; no scattered tax/VAT code.
-
Grouping and aggregation
— Build reports — totals per category, user activity summaries, lists bucketed by status — by composing groupBy, map, and fold. Replace multi-pass code with one declarative pipeline.
-
Imperative vs composed — same job, two shapes
— Side-by-side comparison of the same workflow written two ways. Imperative code on the left, composed pipeline on the right — highlighting fewer temporary variables, clearer data flow, and individual pieces you can reuse and test.
-
Working safely with infinite Generators
— Pipe an infinite Generator through filter / map / take without ever materialising it. Learn which Arrays functions are safe (lazy and short-circuit) and which will hang forever (terminal).
-
Using library functions instead of fn() lambdas
— A practical reference for swapping inline arrow-function predicates for composable library calls. Shorter, more reusable, and — most importantly — named for what they do instead of how they do it.
-
Streaming log processing
— Parse, filter, enrich, and format log lines as a lazy Generator pipeline — you can feed it a multi-gigabyte log file and it only holds a handful of lines in memory at once. Rearrange the stages by reordering the pipeline.
-
Normalising messy API payloads
— Take a raw third-party response and reshape it into a consistent internal format — trim strings, cast types, rename keys, drop nulls — as one reusable compose() pipeline. The same pipeline works for one record or a list via array_map.
-
Null-safe pipelines
— Build pipelines that gracefully abort or default when they hit missing data, without littering every step with `if ($x !== null)` checks. Three approaches — composeSafe, composeTypeSafe, and ifThen / always guards — each suited to a different shape of problem.
-
Preconfigured filters — "ready-made" predicates
— Use partial application to turn generic filter conditions into named, intention-revealing callables — "active users", "recent orders", "high-value transactions" — then reuse them across the app instead of repeating the predicate every time.
-
Sanitising form input
— Build a once-and-reuse sanitisation pipeline for form fields — trim, strip tags, lowercase emails, default missing values — then apply the same pipeline across every form in the app by composition.
-
Validation chains with error accumulation
— Compose small single-purpose validators into a single check that either passes or returns a list of every problem. Compare with imperative validation code that short-circuits on the first failure.