-
Notifications
You must be signed in to change notification settings - Fork 10
/
MonadLaws.php
45 lines (38 loc) · 1.25 KB
/
MonadLaws.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php
declare(strict_types=1);
namespace FunctionalPHP\FantasyLand\Helpful;
use function FunctionalPHP\FantasyLand\bind;
class MonadLaws
{
/**
* Generic test to verify if a type obey the monad laws.
*
* @param callable $assertEqual Asserting function (Monad $m1, Monad $m2, $message)
* @param callable $return Monad "constructor"
* @param callable $f Monadic function
* @param callable $g Monadic function
* @param mixed $x Value to put into a monad
*/
public static function test(
callable $assertEqual,
callable $return,
callable $f,
callable $g,
$x
) {
// Make reading bellow tests easier
$m = $return($x);
// left identity: (return x) >>= f ≡ f x
$assertEqual(bind($f, $return($x)), $f($x), 'left identity');
// right identity: m >>= return ≡ m
$assertEqual(bind($return, $m), $m, 'right identity');
// associativity: (m >>= f) >>= g ≡ m >>= ( \x -> (f x >>= g) )
$assertEqual(
bind($g, bind($f, $m)),
bind(function ($x) use ($f, $g) {
return bind($g, $f($x));
}, $m),
'associativity'
);
}
}