function fmap(...$args) { $f = function (callable $f, $a) { return Loader::callInstanceMethod($a, 'fmap', $f, $a); }; if (count($args) === 2) { return $f(...$args); } else { return f($f, ...$args); } }
function ap(...$args) { $f = function ($f, $g) { return Loader::callInstanceMethod($f, 'ap', $f, $g); }; if (count($args) === 2) { return $f(...$args); } else { return f($f, ...$args); } }
public function cast($m) { if (is_object($m) || is_string($m) || is_array($m)) { $args = []; if (!$this->value instanceof Nul) { $args[] = $this->value; } $ret = Loader::callInstanceMethod($m, $this->op, ...$args); return $this->opsFold($ret); } throw new \Exception('Unsupported cast [' . gettype($m) . ']'); }
function bind(...$args) { $f = function ($m, callable $f) { $ret = Loader::callInstanceMethod($m, 'bind', $m, $f); if ($ret instanceof Any) { $ret = $ret->cast($m); } return $ret; }; if (count($args) === 2) { return $f(...$args); } else { return f($f, ...$args); } }
function mplus(...$args) { $f = function ($m1, $m2) { if ($m1 instanceof Any && !$m2 instanceof Any) { $m1 = $m1->cast($m2); } else { if ($m2 instanceof Any && !$m1 instanceof Any) { $m2 = $m2->cast($m1); } } return Loader::callInstanceMethod($m1, 'mplus', $m1, $m2); }; if (count($args) === 2) { return $f(...$args); } else { return f($f, ...$args); } }
public function __call($name, $args) { $methods = ['ret', 'mempty', 'mzero', 'pure']; // $self = $this; // if ($self instanceof Any && // isset($args[0]) && // !($args[0] instanceof Any)) // $self = $self->cast($args[0]); // else if (isset($args[0]) && // $args[0] instanceof Any && // !($self instanceof Any)) // $args[0] = $args[0]->cast($self); if (in_array($name, $methods)) { return Loader::callFunction($name, ...$args); } array_unshift($args, $this); return Loader::callFunction($name, ...$args); }
<?php namespace Laiz\Func; use Laiz\Func; use Laiz\Func\Any; use Laiz\Func\Unit; Loader::load(); function c(callable $f) { return new Func\Curry($f); } function f(callable $f, ...$args) { if (!$f instanceof Func\Func) { $f = new Func\Func($f); } if ($args) { $f = $f(...$args); } return $f; } // Func function compose(...$args) { return f(function (callable $g, callable $f, $a) { return $g($f($a)); }, ...$args); } function id(...$args) {
<?php namespace Laiz\Test\Func; use Laiz\Func; \Laiz\Func\Loader::load(); class AnyTest extends \PHPUnit_Framework_TestCase { public function testWriterMonad() { $ret = runWriter(ret(1)->bind(function ($_) { return ret(2); })->bind(function ($a) { return tell("a")->bind(function ($_) use($a) { return ret($a + 5); }); })); $this->assertEquals([7, "a"], $ret); } }