cypresslab / php-curry
PHP中的柯里化函数
0.5.0
2017-03-10 17:05 UTC
Requires
- php: >=5.3.2
Requires (Dev)
- phpunit/phpunit: ~6.0
README
PHP中柯里化的实现
柯里化函数意味着能够向函数传递一部分参数,并返回另一个接受其余参数的函数。一旦传递了最后一个参数,它就会得到最终的结果。
例如
use Cypress\Curry as C; $adder = function ($a, $b, $c, $d) { return $a + $b + $c + $d; }; $firstTwo = C\curry($adder, 1, 2); echo $firstTwo(3, 4); // output 10 $firstThree = $firstTwo(3); echo $firstThree(14); // output 20
柯里化是一个强大(但简单)的概念,在其他的更纯粹的函数式语言中非常流行。例如,在Haskell中,柯里化是每个函数的默认行为。
在PHP中,我们仍然需要依赖于包装器来模拟这种行为
如何安装
composer require cypresslab/php-curry
在你的PHP脚本中(已安装composer自动加载器)只需导入命名空间并使用它!
use Cypress\Curry as C; $chunker = C\curry('array_chunk', ['a', 'b']); var_dump($chunker(1)); // output [['a'], ['b']] var_dump($chunker(2)); // output [['a', 'b']]
从右到左
可以从前(默认)或从右进行函数柯里化。
$divider = function ($a, $b) { return $a / $b; }; $divide10By = C\curry($divider, 10); $divideBy10 = C\curry_right($divider, 10); echo $divide10By(10); // output 1 echo $divideBy10(100); // output 10
参数为数组
您还可以将函数柯里化并将参数作为数组传递,只需使用函数的*_args版本即可。
use Cypress\Curry as C; $divider = function ($a, $b) { return $a / $b; }; $division = C\curry_args($divider, [100, 10]); echo $division(); // output 10 $division2 = C\curry_right_args($divider, [100, 10]); echo $division2(); // output 0.1
可选参数
可选参数和柯里化并不总是很好地配合。此库默认排除可选参数。
$haystack = "haystack"; $searches = ['h', 'a', 'z']; $strpos = C\curry('strpos', $haystack); // You can pass function as string too! var_dump(array_map($strpos, $searches)); // output [0, 1, false]
但是strpos有一个可选的$offset参数,默认情况下尚未考虑。
如果您想考虑这个可选的$offset参数,应该将curry“固定”为给定长度。
$haystack = "haystack"; $searches = ['h', 'a', 'z']; $strpos = C\curry_fixed(3, 'strpos', $haystack); $finders = array_map($strpos, $searches); var_dump(array_map(function ($finder) { return $finder(2); }, $finders)); // output [false, 5, false]
curry_right有一个名为curry_right_fixed的固定版本
占位符
函数__()
获得一个特殊的占位符值,用于在柯里化函数中指定“间隔”,允许部分应用任何组合的参数,无论其位置如何。
$add = function($x, $y) { return $x + $y; }; $reduce = C\curry('array_reduce'); $sum = $reduce(C\__(), $add); echo $sum([1, 2, 3, 4], 0); // output 10
注意:
-
仅应使用占位符来指定必需参数。
-
当使用时,可选参数必须位于参数列表的末尾。