Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ircmaxell/monad-php
A simple Monad library for PHP
https://github.com/ircmaxell/monad-php
Last synced: 7 days ago
JSON representation
A simple Monad library for PHP
- Host: GitHub
- URL: https://github.com/ircmaxell/monad-php
- Owner: ircmaxell
- Created: 2013-07-03T15:40:02.000Z (over 11 years ago)
- Default Branch: master
- Last Pushed: 2015-09-10T05:41:57.000Z (about 9 years ago)
- Last Synced: 2024-08-02T16:47:11.664Z (3 months ago)
- Language: PHP
- Size: 228 KB
- Stars: 296
- Watchers: 18
- Forks: 37
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-php-cn - Monad PHP - 一个简单Monad库 (目录 / 数据结构和存储 Data Structure and Storage)
README
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);
// nullThis 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 aboveReal 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]")),
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!