A simple Monad library for PHP

Overview

MonadPHP

This is a basic Monad library for PHP.

Usage

Values are "wrapped" in the monad via either the constructor: new MonadPHP\Identity($value) or the unit() method on an existing instance: $monad->unit($value);

Functions can be called on the wrapped value using bind():

use MonadPHP\Identity;
$monad = new Identity(1);
$monad->bind(function($value) { var_dump($value); });
// Prints int(1)

All calls to bind return a new monad instance wrapping the return value of the function.

 use MonadPHP\Identity;
$monad = new Identity(1);
$monad->bind(function($value) {
        return 2 * $value;
    })->bind(function($value) { 
        var_dump($value); 
    });
// Prints int(2)

Additionally, "extracting" the raw value is supported as well (since this is PHP and not a pure functional language)...

use MonadPHP\Identity;
$monad = new Identity(1);
var_dump($monad->extract());
// Prints int(1)

Maybe Monad

One of the first useful monads, is the Maybe monad. The value here is that it will only call the callback provided to bind() if the value it wraps is not null.

use MonadPHP\Maybe;
$monad = new Maybe(1);
$monad->bind(function($value) { var_dump($value); });
// prints int(1)

$monad = new Maybe(null);
$monad->bind(function($value) { var_dump($value); });
// prints nothing (callback never called)...

The included Chain monad does the same thing, but providing a short-cut implementation for objects:

use MonadPHP\Chain;
$monad = new Chain($someChainableObject);
$obj = $monad->call1()->call2()->nonExistantMethod()->call4()->extract();
var_dump($obj);
// null

This can prevent errors when used with chaining...

List Monad

This abstracts away the concept of a list of items (an array):

use MonadPHP\ListMonad;
$monad = new ListMonad(array(1, 2, 3, 4));
$doubled = $monad->bind(function($value) { return 2 * $value; });
var_dump($doubled->extract());
// Prints array(2, 4, 6, 8)

Note that the passed in function gets called once per value, so it only ever deals with a single element, never the entire array...

It also works with any Traversable object (like iterators, etc). Just be aware that returning the new monad that's wrapped will alwyas become an array...

Composition

These Monads can be composed together to do some really useful things:

use MonadPHP\ListMonad;
use MonadPHP\Maybe;

$monad = new ListMonad(array(1, 2, 3, null, 4));
$newMonad = $monad->bind(function($value) { return new Maybe($value); });
$doubled = $newMonad->bind(function($value) { return 2 * $value; });
var_dump($doubled->extract());
// Prints array(2, 4, 6, null, 8)

Or, what if you want to deal with multi-dimensional arrays?

use MonadPHP\ListMonad;
$monad = new ListMonad(array(array(1, 2), array(3, 4), array(5, 6)));
$newMonad = $monad->bind(function($value) { return new ListMonad($value); });
$doubled = $newMonad->bind(function($value) { return 2 * $value; });
var_dump($doubled->extract());
// Prints array(array(2, 4), array(6, 8), array(10, 12))

There also exist helper constants on each of the monads to get a callback to the unit method:

$newMonad = $monad->bind(Maybe::unit);
// Does the same thing as above 

Real World Example

Imagine that you want to traverse a multi-dimensional array to create a list of values of a particular sub-key. For example:

$posts = array(
    array("title" => "foo", "author" => array("name" => "Bob", "email" => "[email protected]example.com")),
    array("title" => "bar", "author" => array("name" => "Tom", "email" => "[email protected]")),
    array("title" => "baz"),
    array("title" => "biz", "author" => array("name" => "Mark", "email" => "[email protected]")),
);

What if we wanted to extract all author names from this data set. In traditional procedural programming, you'd likely have a number of loops and conditionals. With monads, it becomes quite simple.

First, we define a function to return a particular index of an array:

function index($key) {
    return function($array) use ($key) {
        return isset($array[$key]) ? $array[$key] : null;
    };
}

Basically, this just creates a callback which will return a particular array key if it exists. With this, we have everything we need to get the list of authors.

$postMonad = new MonadPHP\ListMonad($posts);
$names = $postMonad
    ->bind(MonadPHP\Maybe::unit)
    ->bind(index("author"))
    ->bind(index("name"))
    ->extract();

Follow through and see what happens!

You might also like...
EmailReplyParser is a PHP library for parsing plain text email content, based on GitHub's email_reply_parser library written in Ruby

EmailReplyParser EmailReplyParser is a PHP library for parsing plain text email content, based on GitHub's email_reply_parser library written in Ruby.

Library JGU is a website created for a university library system information. Made with PHP & TailwindCSS.
Library JGU is a website created for a university library system information. Made with PHP & TailwindCSS.

Library JGU Library JGU is a website created for a university library system information. Made with PHP & TailwindCSS. Key Features • How To Use • Rel

Simple PHP Pages - A simple puristic PHP Website Boilerplate
Simple PHP Pages - A simple puristic PHP Website Boilerplate

Simple PHP Pages - A simple puristic PHP Website Boilerplate 🚀 Hey! This project provides simple and basic concepts for PHP pages. It includes ideas

Simple utility and class library for generating php classes from a wsdl file.

wsdl2phpgenerator Simple WSDL to PHP classes converter. Takes a WSDL file and outputs class files ready to use. Uses the MIT license. Announcement: We

Événement is a very simple event dispatching library for PHP.

Événement Événement is a very simple event dispatching library for PHP. It has the same design goals as Silex and Pimple, to empower the user while st

A simple filtering library for PHP

Filterus - A flexible PHP 5.3 filter package Filter Methods: Each filter class has two primary methods: $filter-filter($var) - returns a modified ver

Simple Yet Powerful Geo Library for PHP

phpgeo - A Simple Geo Library for PHP phpgeo provides abstractions to geographical coordinates (including support for different ellipsoids) and allows

PHP logging library that is highly extendable and simple to use.

Analog - Minimal PHP logging library Copyright: (c) 2012-Present Johnny Broadway License: MIT A minimal PHP logging package based on the idea of using

A simple PHP library for handling Emoji

Emoji Emoji images from unicode characters and names (i.e. :sunrise:). Built to work with Twemoji images. use HeyUpdate\Emoji\Emoji; use HeyUpdate\Emo

Sslurp is a simple library which aims to make properly dealing with SSL in PHP suck less.

Sslurp v1.0 by Evan Coury Introduction Dealing with SSL properly in PHP is a pain in the ass and completely insecure by default. Sslurp aims to make i

Simple yet powerful Excel manipulation library for PHP 5.4+

| | \ / \_/ __ /^\ __ ' `. \_/ ,' ` \/ \/ _,--./| |\.--._ _,' _.-\_/-._ `._ | / \ | |

TCrypto is a simple and flexible PHP 5.3+ in-memory key-value storage library

About TCrypto is a simple and flexible PHP 5.3+ in-memory key-value storage library. By default, a cookie will be used as a storage backend. TCrypto h

Purl is a simple Object Oriented URL manipulation library for PHP 7.2+

Purl Purl is a simple Object Oriented URL manipulation library for PHP 7.2+ Installation The suggested installation method is via composer: composer r

A simple PHP library for handling Emoji

Emoji Emoji images from unicode characters and names (i.e. :sunrise:). Built to work with Twemoji images. use HeyUpdate\Emoji\Emoji; use HeyUpdate\Emo

Currency is a simple PHP library for current and historical currency exchange rates & crypto exchange rates. based on the free API exchangerate.host

Currency Currency is a simple PHP library for current and historical currency exchange rates & crypto exchange rates. based on the free API exchangera

Simple yet expressive schema-based configuration library for PHP apps

league/config helps you define nested configuration arrays with strict schemas and access configuration values with dot notation.

A simple object-relational mapping library built using PHP.

A simple object-relational mapping library built using PHP.

A simple Atom/RSS parsing library for PHP.

SimplePie SimplePie is a very fast and easy-to-use class, written in PHP, that puts the 'simple' back into 'really simple syndication'. Flexible enoug

A simple PHP library for complex monetary prices management

PHP Prices 💸 Version 2.x This new major version is shifting the package towards more flexibility and configuration possibilities in general. One of t

Comments
  • Remove [const unit], and refactoring

    Remove [const unit], and refactoring

    in php 5.3 we not need $this->unit(...) we can use static::unit without any const and any duplicate code in brackets look like '"MonadPHP\Identity::unit"

    opened by mekegi 0
  • Fixed strict error

    Fixed strict error "Declaration of *::bind() should be compatible with Monad::bind()"

    Original code throws strict error "Declaration of Maybe::bind() should be compatible with Monad::bind($function, array $args = Array)" when "error_reporting = E_STRICT" is set in php.ini.

    Avoid this issue, base Monad class should not implement bind function. But Monad class can implement magic method, and implement bind method in it.

    opened by katsuren 0
Owner
Anthony Ferrara
Anthony Ferrara
A simple stateless production rules engine for PHP 5.3+

Ruler Ruler is a simple stateless production rules engine for PHP 5.3+. Ruler has an easy, straightforward DSL ... provided by the RuleBuilder: $rb =

Justin Hileman 1k Dec 28, 2022
sample code for several design patterns in PHP 8

DesignPatternsPHP Read the Docs of DesignPatternsPHP or Download as PDF/Epub This is a collection of known design patterns and some sample codes on ho

null 21k Jan 1, 2023
Primitives for functional programming in PHP

Functional PHP: Functional primitives for PHP NOTE: functional-php used to come with a C extension that implemented most of the functions natively. As

Lars Strojny 1.9k Jan 3, 2023
Option Type for PHP

PHP Option Type This package implements the Option type for PHP! Motivation The Option type is intended for cases where you sometimes might return a v

Johannes 2.4k Dec 26, 2022
Powerful implementation of the Specification pattern in PHP

RulerZ The central idea of Specification is to separate the statement of how to match a candidate, from the candidate object that it is matched agains

Kévin Gomez 865 Dec 22, 2022
A simple wrapper for PHP Intervention Library to provide a more simple interface and convenient way to convert images to webp

This package is a simple wrapper for PHP Intervention Library to provide a more simple interface and convenient way to convert images to webp - next generation format - extension, and resize them to render only needed sizes.

eyad hamza 18 Jun 28, 2022
Simple library that abstracts different metrics collectors. I find this necessary to have a consistent and simple metrics (functional) API that doesn't cause vendor lock-in.

Metrics Simple library that abstracts different metrics collectors. I find this necessary to have a consistent and simple metrics API that doesn't cau

Benjamin Eberlei 311 Nov 20, 2022
PHP Exif Library - library for reading and writing Exif headers in JPEG and TIFF files using PHP.

PEL: PHP Exif Library README file for PEL: PHP Exif Library. A library with support for reading and writing Exif headers in JPEG and TIFF images using

null 264 Dec 4, 2022
Columnar analytics for PHP - a pure PHP library to read and write simple columnar files in a performant way.

Columnar Analytics (in pure PHP) On GitHub: https://github.com/envoymediagroup/columna About the project What does it do? This library allows you to w

Envoy Media Group 2 Sep 26, 2022
BeckhoffPLCSoapClient - SoapClient to communicate with BeckHoff PLC. Library made in PHP based on TcAdsWebService JavaScript Library.

BeckhoffPLCSoapClient - SoapClient to communicate with BeckHoff PLC. Library made in PHP based on TcAdsWebService JavaScript Library.

null 3 May 18, 2022