effect-ts-folds: Recursion Schemes for the Effect Runtime
A compact TypeScript library that turns folds, unfolds, and refolds into stack-safe Effect programs, so the recursion engine disappears and the algebra becomes the point.
- effect-ts-folds makes recursion a job for the Effect runtime, not the JavaScript call stack.
- Its real move is to separate traversal shape from node meaning, so developers write algebras instead of recursive control flow.
- The library is small, but it pushes TypeScript and Effect into a highly disciplined algebraic model for stack-safe tree processing.
- Its best case is advanced recursive data where safety, composition, and one-pass efficiency matter more than simplicity.
The recursion problem Effect solves here
Recursive traversals are easy to write until they are not. A deep tree, a large JSON document, or a sprawling AST can turn a clean function into a stack overflow error. effect-ts-folds changes the failure mode by moving the recursion into Effect itself.
That is the whole bet. The library is not trying to make recursion prettier. It is trying to make recursion behave like a managed program, where each step can suspend, resume, and compose without depending on the JavaScript call stack.
// The point is not the exact syntax here.
// The point is the shape: recurse through Effect, not through raw JS calls.
const total = cataE(algebra)(value)
The library’s core idea: recursion schemes without the recursion tax
The library is built around recursion schemes. That means the developer does not describe how to recurse through a structure. They describe what each node means, and the library handles the traversal shape. In practice, that shifts the focus from control flow to algebra.
A catamorphism collapses a structure. An anamorphism builds one. A hylomorphism does both. The important part is that these are not just named folds with fancy syntax. They are a way to make recursion explicit at the level of meaning, while the runtime handles the execution details.
The repo’s structure reflects that discipline. There are separate areas for fixed points, folds, unfolds, and refolds, plus utility code for the type-level machinery that TypeScript needs in order to model higher-kinded abstractions.
Why Effect is doing more than side effects
The suffix matters. Functions like cataE are not decorative names. The E signals that evaluation itself is effectful, which means recursion can be suspended, sequenced, and resumed inside the Effect runtime instead of being forced through raw function calls.
That is why the stack stays safe. The library uses Effect combinators such as Effect.suspend and Effect.flatMap to turn recursive descent into a controlled fiber-driven process. The traversal still visits every node. It just does not accumulate JavaScript frames while it does so.
This is the sharpest idea in the project. Effect is not only carrying errors or async work here. It is carrying the recursion itself.
The fixed point trick that makes recursive data types usable
TypeScript does not give you native higher-kinded types, so recursive algebraic libraries have to work harder. Fix is the classic answer. It wraps a recursive shape so the library can talk about the shape generically instead of hardcoding a particular tree or list.
That sounds abstract because it is abstract. But the practical payoff is simple: the same machinery can describe many recursive data structures, and the fold logic does not have to be rewritten for each one. The structure becomes data. The traversal becomes reusable.
| Approach | Runtime model | Stack safety | Type abstraction | Multi-pass optimization | Best use case |
|---|---|---|---|---|---|
| Hand-written recursion | Direct JS calls | Depends on depth | Low | No | Small, simple traversals |
| fp-ts style abstractions | Library-level combinators | Usually manual | High | Sometimes | General functional programming |
| effect-ts-folds | Effect runtime and fibers | Built in | High | Yes, with zipFolds | Deep recursive structures with effects |
The one-pass optimization: folding many answers at once
A good library does not only make hard things possible. It also removes avoidable work. One of the nicest practical moves here is zipFolds, which lets you compute multiple results in a single traversal.
That means sum, max, count, or validation can all happen together instead of in separate passes. For large structures, this matters. For advanced users, it also proves the abstraction is not just elegant. It is operationally serious.
// Sketch only.
// One traversal, many answers.
const combined = zipFolds(sumFold, maxFold, countFold)
const result = cataE(combined)(tree)
Where the abstractions get serious
The advanced schemes are where the library stops looking like a convenience wrapper and starts looking like a serious algebraic toolkit. Histomorphisms give a fold access to prior results. Hylomorphisms generate and then collapse a structure without forcing you to materialize every intermediate step in your own code.
That is the real power of the model. Once recursion is abstracted cleanly enough, the runtime can support richer strategies without changing the shape of the user’s code. The developer chooses the scheme. The library handles the traversal.
This library provides foldable and traversable implementations for types in the Effect ecosystem.
How it compares to fp-ts, plain Effect, and hand-written recursion
The comparison is not subtle. Hand-written recursion is still the easiest answer for small tasks. fp-ts gives TypeScript a broad functional vocabulary. Effect gives it a runtime built for structured concurrency, error handling, and composable programs.
effect-ts-folds sits in the narrow space where those ideas overlap. It is for people who want the abstraction density of recursion schemes and the execution model of Effect, without gluing two ecosystems together by hand.
| Approach | What you get | What you give up |
|---|---|---|
| Hand-written recursion | Maximum simplicity for tiny problems | Safety and reuse at depth |
| fp-ts | A broad functional baseline | Native Effect integration |
| effect-ts-folds | Effect-native recursion schemes | Breadth and beginner friendliness |
What kind of project is this, really?
This is a specialized library for people who already care about the Effect ecosystem and the algebra behind recursive data. It is not trying to be a mass-market utility. Its significance is narrower and more interesting than that: it shows how far the Effect model can be pushed when recursion itself becomes part of the runtime story.
The codebase is small, disciplined, and intentionally technical. That makes it valuable as a signal. It says the Effect world is not just building applications. It is building a serious language for describing them.





