PHPackages                             khalyomede/monad - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. khalyomede/monad

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

khalyomede/monad
================

Maybe, Option and Result monads.

0.2.1(4y ago)318[1 issues](https://github.com/khalyomede/monad/issues)MITPHP

Since Aug 7Pushed 3y ago1 watchersCompare

[ Source](https://github.com/khalyomede/monad)[ Packagist](https://packagist.org/packages/khalyomede/monad)[ Docs](https://github.com/khalyomede/monad)[ RSS](/packages/khalyomede-monad/feed)WikiDiscussions master Synced today

READMEChangelogDependencies (6)Versions (4)Used By (0)

khalyomede/monad
================

[](#khalyomedemonad)

Maybe, Option and Result monads for PHP.

Summary
-------

[](#summary)

- [About](#about)
- [Features](#features)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Examples](#examples)
- [API](#api)

About
-----

[](#about)

I published on [reddit](https://www.reddit.com/r/PHP/comments/oxcmw9/rfc_proposal_enums_constructor/) an RFC proposal for what I called "enums constructor" (which happened to be an existing concept called "tagged unions"). Out of [one comment](https://www.reddit.com/r/PHP/comments/oxcmw9/rfc_proposal_enums_constructor/h7qgo1n?utm_source=share&utm_medium=web2x&context=3), I shown how to chain calls to various ADT outcomes, in order to reduces pyramidal matches.

This got me into wanting to use more monads right now on my next projects. After searching on packagist.org, I did not found something that fits what I expected, so I decided to make my own version of how I think monads should look like in PHP.

Features
--------

[](#features)

- Supports theses monads:
    - Option
    - Maybe
    - Result
- PHPStan and static analyzers friendly

Prerequisites
-------------

[](#prerequisites)

- PHP 8+ installed

Installation
------------

[](#installation)

```
composer require khalyomede/monad
```

Examples
--------

[](#examples)

- [1. Getting a file content](#1-getting-a-file-content)
- [2. Get users from an SQL table](#2-get-users-from-an-sql-table)
- [3. Chain multiple outcomes](#3-chain-multiple-outcomes)

### 1. Getting a file content

[](#1-getting-a-file-content)

In this example, we will use the Maybe monad as result, and use it in our main code.

```
use Khalyomede\Monad\Maybe;

function getFileContent(string $filePath): Maybe
{
  $content = file_get_contents($filePath);

  return $content === false ? Maybe::nothing() : Maybe::just($content);
}

// main
$content = getFileContent("data.txt")
  ->then(fn (string $data): string => $data)
  ->catch(fn (): string => "N/A");

echo $content;
```

### 2. Get users from an SQL table

[](#2-get-users-from-an-sql-table)

In this example, we will use the Result monad to return the list of users or an error from PDO.

```
use Khalyomede\Monad\Result;

function getUsers(): Result
{
  $pdo = new PDO("sqlite::memory:");

  $statement = $pdo->prepare("SELECT * FROM users");

  if ($statement === false) {
    $message = $pdo->errorInfo()[2];

    return Result::error($message);
  }

  $result = $statement->execute();

  if ($result === false) {
    $message = $statement->errorInfo()[2];

    return Result::error($message);
  }

  return Result::ok($statement->fetchAll());
}

// main
$users = getUsers()
  ->then(fn (array $records): array => $records)
  ->catch(function (string $error): array {
    error_log($error);

    return [];
  });
```

### 3. Chain multiple outcomes

[](#3-chain-multiple-outcomes)

In this example, we will chain multiple times "then", similar to what is possible in other languages through "map".

```
use Khalyomede\Monad\Result;

function getFileContent(string $path): Result
{
  $content = file_get_contents($path);

  return $content === false ?
    Result::error(new Exception("Cannot get content of file $path.")) :
    Result::ok($content);
}

function saveFileContent(string $path, string $content): Result
{
  $result = file_put_contents($path, $content);

  return $result === false ?
    Result::error(new Exception("Cannot write file content of file $path.")) :
    Result::ok(true);
}

// main
$result = fileGetContent("composer.json")
  ->then(fn (string $content): Result => saveFileContent("composer.json.save", $content))
  ->then(fn (): string => "composer.json backup finished.")
  ->catch(fn (Exception $exception): string => $exception->getMessage());

echo $result . PHP_EOL;
```

```
khalyomede@pc > php index.php
composer.json backup finished.
```

If you remove the file, the result becomes

```
khalyomede@pc > php index.php
Cannot get content of file composer.json.
```

If you remove the write permission on this file, the result becomes

```
khalyomede@pc > php index.php
Cannot write file content of file composer.json.save.
```

API
---

[](#api)

For a list of all possible functions, see the *tests\\unit* folder.

Tests
-----

[](#tests)

```
composer run install-security-checker
composer run test
composer run mutate
composer run analyse
composer run check
composer outdated --direct
```

###  Health Score

20

—

LowBetter than 14% of packages

Maintenance13

Infrequent updates — may be unmaintained

Popularity10

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

1738d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/15908747?v=4)[Anwar](/maintainers/khalyomede)[@khalyomede](https://github.com/khalyomede)

---

Top Contributors

[![khalyomede](https://avatars.githubusercontent.com/u/15908747?v=4)](https://github.com/khalyomede "khalyomede (22 commits)")

---

Tags

adtfunctional-programmingmonadfunctionalprogrammingmonadADT

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/khalyomede-monad/health.svg)

```
[![Health](https://phpackages.com/badges/khalyomede-monad/health.svg)](https://phpackages.com/packages/khalyomede-monad)
```

###  Alternatives

[lstrojny/functional-php

Functional primitives for PHP

2.0k7.3M48](/packages/lstrojny-functional-php)[nikic/iter

Iteration primitives using generators

1.1k5.9M38](/packages/nikic-iter)[ihor/nspl

Non-standard PHP library (NSPL) - functional primitives toolbox and more

381368.5k](/packages/ihor-nspl)[lambdish/phunctional

λ PHP functional library

3612.0M23](/packages/lambdish-phunctional)[crell/fp

Functional utilities for PHP 8 and later

91429.8k11](/packages/crell-fp)[chippyash/monad

Functional programming Monad support

2828.1k8](/packages/chippyash-monad)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
