public static function mappend($m1, $m2) { assert($m1 instanceof Instance, 'First argument must be Func'); assert($m2 instanceof Instance, 'Second argument must be Func'); return f(function ($f, $g, $a) { return mappend($f($a), $g($a)); }, $m1, $m2); }
public function testBind() { $f = f(function ($a) { return $a - 2; }); $ret = $f->bind(f(function ($a, $b) { return $a - $b; })); $this->assertEquals(-2, $ret(4)); }
function maybe(...$args) { return f(function ($b, callable $f, Maybe $m) { if ($m instanceof Maybe\Just) { return $f($m->fromJust()); } else { return $b; } }, ...$args); }
function guard(...$args) { return f(function ($a) { if ($a) { return Func\Applicative\pure(new Func\Unit()); } else { return Func\MonadZero\mzero(); } }, ...$args); }
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 ret(...$args) { $f = function ($a) { return new Any('ret', $a); }; if (count($args) === 1) { return $f(...$args); } else { return f($f, ...$args); } }
function const2(...$args) { $f = function ($a1, $a2) { return ap(fconst(id(), $a1), $a2); }; 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 static function ap($f, $g) { return f(function ($f, $g, $a) { return $f($a, $g($a)); }, $f, $g); }
public function testGuardAppend() { $f = function ($s, ...$eq) { return f(function ($s, $a, $b) { return fconst($s, guard($a === $b)); }, $s, ...$eq); }; $at = $f('a', 1, 1); $af = $f('a', 1, 2); $bt = $f('b', 2, 2); $bf = $f('b', 2, 3); $this->assertEquals(Just('a'), $at->cast(Nothing())); $this->assertEquals(Nothing(), $af->cast(Nothing())); $this->assertEquals(Just('b'), $bt->cast(Nothing())); $this->assertEquals(Nothing(), $bf->cast(Nothing())); $this->assertEquals(Nothing(), mappend($af, $bf)->cast(Nothing())); $this->assertEquals(Just('a'), mappend($at, $bf)->cast(Nothing())); $this->assertEquals(Just('b'), mappend($af, $bt)->cast(Nothing())); $this->assertEquals(Just('ab'), mappend($at, $bt)->cast(Nothing())); $this->assertEquals(Nothing(), mappend($f('a', 1), $f('b', 1), 2)->cast(Nothing())); $this->assertEquals(Just('a'), mappend($f('a', 2), $f('b', 1), 2)->cast(Nothing())); $this->assertEquals(Just('b'), mappend($f('a', 1), $f('b', 2), 2)->cast(Nothing())); $this->assertEquals(Just('ab'), mappend($f('a', 2), $f('b', 2), 2)->cast(Nothing())); }
function runWriter(...$args) { return f(function (Writer $w) { return [$w->a, $w->w]; }, ...$args); }
public static function ret($a) { return f(function ($_) use($a) { return $a; }); }
public function testFmap() { $m1 = Just(3); $f1 = function ($a) { return $a + 1; }; $this->assertEquals(Just(4), fmap($f1, $m1)); $f2 = f(function ($a, $b) { return $a + $b; }); $mf = fmap($f2, $m1); $this->assertInstanceOf('Laiz\\Func\\Maybe', $mf); $a = fmap(function ($f) { return $f(4); }, $mf); $this->assertEquals(Just(7), $a); $m2 = Just(2); $this->assertEquals(Just(5), ap($mf, $m2)); }