* * Full license available in separate LICENSE file */ use \Kadet\Functional as f; use const Kadet\Functional\_; function subtract($a, $b) { return $a - $b; } class PartialApplicationTest extends \PHPUnit\Framework\TestCase { public function testPartialApplicationOfOneArgument() { $applied = f\partial('subtract', 10); $this->assertEquals(0, $applied(10)); $this->assertEquals(10, $applied(0)); $this->assertEquals(20, $applied(-10)); } public function testPartialApplicationOfAllArguments() { $applied = f\partial('subtract', 10, 20); $this->assertEquals(-10, $applied()); } public function testPartialApplicationOfFewArguments() { $applied = f\partial('array_merge', ['a'], ['b'], ['c']); $this->assertEquals(['a', 'b', 'c', 'd', 'e'], $applied(['d'], ['e'])); } public function testPartialApplicationWithPlaceholders() { $applied = f\partial('array_merge', ['a'], _, ['c']); $this->assertEquals(['a', 'd', 'c'], $applied(['d'])); } public function testPartialApplicationOfAppliedFunction() { $applied = f\partial('array_merge', ['a'], _, ['c']); $double = f\partial($applied, _, ['d']); $this->assertEquals(['a', 'b', 'c', 'd', 'e'], $double(['b'], ['e'])); } public function testDecoration() { $x = function() {}; $applied = f\partial($x); $this->assertSame($applied->getDecorated(), $x); } public function testArgumentProviding() { $applied = f\partial('array_merge', ['a'], _, ['c']); $this->assertSame( [0 => ['a'], 2 => ['c']], $applied->getArguments() ); } public function testYCombinator() { $applied = f\fix(function ($f) use (&$applied) { $this->assertSame($f, $applied); return function ($x) { $this->assertEquals(1, $x); }; }); $applied(1); } public function testYCombinatorFactorial() { $applied = f\fix(function ($f) { return function ($x) use ($f) { return $x >= 2 ? $f($x-1) * $x : 1; }; }); $this->assertEquals(6, $applied(3)); $this->assertEquals(24, $applied(4)); } public function testYCombinatorCurried() { $applied = f\fix(f\curry(function ($f, $x) { return $x >= 2 ? $f($x-1) * $x : 1; })); $this->assertEquals(6, $applied(3)); $this->assertEquals(24, $applied(4)); } public function testPartialApplicationOfAppliedFunctionWithPlaceholders() { $applied = f\partial('array_merge', _, _, ['c']); $double = f\partial($applied, ['a']); $this->assertEquals(['a', 'b', 'c', 'd'], $double(['b'], ['d'])); } }