cypresslab/php-curry

PHP中的柯里化函数

0.5.0 2017-03-10 17:05 UTC

This package is auto-updated.

Last update: 2024-08-29 03:52:49 UTC


README

Code Coverage Build Status SensioLabsInsight

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

注意:

  • 仅应使用占位符来指定必需参数。

  • 当使用时,可选参数必须位于参数列表的末尾。