[][link-scrutinizer] [][link-code-quality]
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();
}
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
.
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.
Via Composer
$ composer require duckson/monads
Please see CHANGELOG for more information what has changed recently.
$ composer test
Please see CONTRIBUTING and CONDUCT for details.
If you discover any security related issues, please email mathijs.bernson@gmail.com instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.