Introdution

Are you a TypeScript developer who loves functional programming? Well, I’ve got something for you: holo-fn – a lightweight, functional library designed to handle optional values, errors, and results in a simple, type-safe, and immutable way.

The name holo-fn is inspired by Holocron from the Star Wars universe. A Holocron is a device used to store vast amounts of knowledge, passed down through the ages. Similarly, holo-fn serves as a repository for powerful, functional programming constructs (like Maybe, Either, and Result), designed to make your TypeScript code cleaner, safer, and more composable.

🎯 Why holo-fn?

holo-fn provides powerful monads like Maybe, Either, and Result. These functional constructs help you write safer, cleaner, and more composable code by handling edge cases like missing values, errors, and successful outcomes in a more predictable and manageable way.

It is built to work seamlessly with the pipe function from Rambda for an even more functional style.

Key Features:

  • Functional types: Maybe, Either, and Result to handle optional values, errors, and results.

  • Immutability: Everything is immutable by default, making your code more predictable and safer.

  • Type Safety: Fully typed with TypeScript, so you can rely on the power of TypeScript’s static analysis.

  • 100% Test Coverage: Rigorously tested with 100% coverage, ensuring stability and reliability.

  • No dependencies: Zero dependencies, keeping your project lightweight.

  • Rambda compatibility: Built to seamlessly work with pipe from Rambda.

📦 Installation

You can easily install holo-fn via npm:

npm install holo-fn

🚀 Getting Started

Here’s a quick example of how to get started with holo-fn.

https://richecr.github.io/holo-fn/getting_started/

Maybe

Maybe is used to handle values that can be null or undefined. It prevents null/undefined errors by wrapping values in a Just (for present values) or Nothing (for absent values).

import { fromNullable } from 'holo-fn/maybe'

const name = fromNullable('Rich')
  .map(n => n.toUpperCase())
  .unwrapOr('Anonymous')

console.log(name) // RICH

You can see the methods that maybe supports on this page.

Either

Either represents a computation that can either succeed (Right) or fail (Left). This is especially useful for error handling, where the left side represents an error and the right side represents a success.

import { Right } from 'holo-fn/either'

const result = new Right(10)
  .map(n => n * 2)
  .unwrapOr(0)

console.log(result); // 20

You can see the methods that either supports on this page.

Result

Result is similar to Either, but specifically designed for operations that can either succeed with a value (Ok) or fail with an error (Err).

import { Ok } from 'holo-fn/result'

const result = new Ok<number, string>(10)
  .map(n => n + 1)
  .unwrapOr(0)

console.log(result) // 11

You can see the methods that result supports on this page.

🛠️ Curried Functions

For a more functional approach, holo-fn also provides curried versions of most methods. You can easily compose them using pipe from Rambda.

Examples:

import { Err, mapErrR } from 'holo-fn/result';

const result = pipe(
  new Err("Error"),
  mapErrR((e) => `Mapped error: ${e}`),
  (res) => res.unwrapOr("No value")
);

console.log(result); // "No value"
import { Left, mapLeftE } from 'holo-fn/either';

const result = pipe(
  new Left("Error"),
  mapLeftE((e) => `Mapped error: ${e}`),
  (res) => res.unwrapOr("No value") 
);

console.log(result); // "No value"

We have documentation for these functions for each type you want to use:

🧠 Why Choose holo-fn?

  • Immutability: All values are immutable by default. This reduces bugs and makes code easier to reason about.

  • Composability: Use map, chain, and unwrapOr for easy composition of functional pipelines.

  • Type Safety: holo-fn is fully typed with TypeScript, making sure your code is safe, with no surprises.

  • Lightweight: It’s designed to be lightweight, with zero dependencies.

  • Rambda-Friendly: Works beautifully with pipe from Rambda, enabling functional programming patterns.

📈 Performance Considerations

Since holo-fn is built for composability and type safety, it also ensures that performance isn’t compromised. The library’s methods are optimized for fast and efficient execution, with minimal overhead.

🤝 Contribute

Want to contribute? We’re open to contributions! If you’re familiar with TypeScript and functional programming, feel free to submit issues or pull requests to improve the library.

You can start by forking the repository and making your changes. Once done, simply submit a pull request!

Here we have a dedicated page for new contributors and feel free to open an issue with any questions.

🔗 Links

Conclusion

holo-fn is a minimal yet powerful library that makes functional programming in TypeScript more approachable. With support for monads like Maybe, Either, and Result, you can easily handle edge cases in a predictable and clean way. Start using it in your TypeScript projects and enjoy the benefits of functional programming!