mbernson / monads

My implementation of some common monads in PHP

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Monads

Latest Version on Packagist Software License Build Status [Coverage Status][link-scrutinizer] [Quality Score][link-code-quality] Total Downloads

This is my implementation of some common monads in PHP. It was mostly inspired by Tom Stuart's talk about refactoring Ruby code with monads. I wrote this library primarily for educational purposes.

I've defined the following interface for my monad implementations:

interface Monad {
    public function bind(callable $fn);
    public function value();
}

Usage

Optional/maybe monad

An Optional object wraps any PHP object or value. It will only call functions on that value when it is not null.

$dateObjectOrNull = new DateTime;
$maybeDate = new Optional($dateObjectOrNull); // You can wrap any PHP value in an optional

$timestamp = $maybeDate->bind(function($value) { // When the wrapped value is `null`, this closure would never be executed
    return $value->format('Y-m-d');
})->value(); // Returns the transformed value, or null if `$dateObjectOrNull` were null

var_dump($timestamp); // string(10) "2016-03-28"

Alternatively, you can use magic methods and properties. Note that you still have to use the value() function to unwrap the monadic value at the end.

This snippet does exactly the same as the previous snippet:

$dateObjectOrNull = new DateTime;
$maybeDate = new Optional($dateObjectOrNull);

$timestamp = $maybeDate->format('Y-m-d')->value();

var_dump($timestamp); // string(10) "2016-03-28"

Again, the call to the format('Y-m-d') instance method will only be forwarded to the wrapped value when it is not null.

Many monad

A Many object executes operations over an array of many objects. It can only be constructed with an array of values. The transformation function that is passed bind() will be applied to each value. This results in an array of transformed values, which is passed to the next monad.

$dates = new Many([
    new \DateTime('yesterday'),
    new \DateTime('now'),
    new \DateTime('tomorrow'),
]);

$timestamps = $dates->bind(function($date) {
    return $date->format('Y-m-d');
})->value();

var_dump($timestamps);
// array(3) {
//   [0] =>
//   string(10) "2016-03-27"
//   [1] =>
//   string(10) "2016-03-28"
//   [2] =>
//   string(10) "2016-03-29"
// }

Again, we can use magic methods or properties to achieve the same result:

$dates = new Many([
    new \DateTime('yesterday'),
    new \DateTime('now'),
    new \DateTime('tomorrow'),
]);

$timestamps = $dates->format('Y-m-d')->value();

var_dump($timestamps);
// The result is the same as above.

Install

Via Composer

$ composer require duckson/monads

Change log

Please see CHANGELOG for more information what has changed recently.

Testing

$ composer test

Contributing

Please see CONTRIBUTING and CONDUCT for details.

Security

If you discover any security related issues, please email mathijs.bernson@gmail.com instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

About

My implementation of some common monads in PHP

License:MIT License


Languages

Language:PHP 100.0%