php-fp / php-fp-combinators
PHP中的一些函数组合子。
Requires
- cypresslab/php-curry: ^0.4.0
Requires (Dev)
- phpunit/phpunit: ^5.7
This package is not auto-updated.
Last update: 2023-06-05 08:43:40 UTC
README
简介
组合子是一些简单的函数,允许您在创建后修改值和函数的行为。这些允许更高效地重用函数并减少样板代码。
API
默认情况下,这些组合子不是完全柯里化的,主要是为了优化原因,但它们设计得足以满足大多数常见用例。因此,类型签名使用逗号(,
)来表示多个参数。
compose :: (b -> c), (a -> b) -> a -> c
而不是编写function ($x) { return f(g(x)); }
,compose
允许我们将其表示为compose('f', 'g')
(其中参数可以是闭包、可调用对象或任何可以用作“函数”的东西)。给定两个函数,f
和g
,将返回一个函数,该函数接受一个值,x
,并返回f(g(x))
。此操作是结合律的,因此compose
调用可以嵌套以创建更长的函数链。这里有一个简单的、两个函数的示例
<?php use PhpFp\Combinators as F; $strictUcFirst = F::compose('ucfirst', 'strtolower'); $strictUcFirst('HELLO, WORLD'); // Hello, world
请注意,函数是按照从左到右的顺序调用的。如果需要相反的顺序,这可以很容易地实现
<?php use PhpFp\Combinators as F; // The `flip` function is discussed later in this document. $pipe = flip(F::compose()); $pipe($f, $g)($x) === $g($f($x));
flip :: (a, b -> c) -> (b, a) -> c
此函数接受一个接受两个参数的函数,并返回相同功能的函数,但参数顺序被交换
<?php use PhpFp\Combinators as F; $divide = function ($x, $y) { return $x / $y; }; $divideBy = F::flip($divide); $divideBy(2, 10); // 5
对于柯里化的函数,此函数非常有用。它在组合链和点无表达式中非常有用。
id :: a -> a
返回它所得到的任何东西!再次,这在组合链中非常有用,当你不希望对值做任何事情时(参见converge
)
<?php use PhpFp\Combinators as F; F::id(2); // 2 F::id('hello'); // hello
ifElse :: (a -> Bool), (a -> b), (a -> b) -> a -> b
此函数允许在组合链中进行条件判断。与分支和合并的converge
不同,ifElse
根据谓词选择要运行的函数,另一个函数将被忽略
<?php use PhpFp\Combinators as F; $isOdd = function ($x) { return $x % 2 === 1; }; $odd = function ($x) { return $x * 3 + 1; }; $even = function ($x) { return $x / 2; }; $collatz = F::ifElse($isOdd, $odd, $even); $collatz(3); // 10 $collatz(10); // 5
K :: a -> b -> a
此函数接受一个值,然后返回一个函数,该函数无论接收什么都会返回该值。这创建了一个“常量”函数来包装值,在需要调用的地方
<?php use function PhpFp\Combinators; $isOdd = function ($x) { return $x % 2 === 1; }; $f = F::ifElse($isOdd, K('Oops!'), function ($x) { return "$x is even!"; }); $f(1); // 'Oops!' $f(2); // '2 is even!'
on :: (b, b -> c), (a -> b) -> a, a -> c
此函数也称为Psi
组合子,允许您对值的变换调用函数。这对于诸如按对象的特定属性排序之类的事情非常有用:我们可以根据变换在两个对象上调用比较函数。最好用一个例子来说明
<?php // Get an array value. $prop = function ($k) { return function ($xs) use ($k) { return $xs[$k]; }; }; // Sort arrays by their 'test' key. $sort = function ($xs, $f) use ($prop) { $ys = array_slice($xs, 0); usort($ys, on($f, $prop('test'))); return $ys; }; // Standard comparison function. $f = function ($a, $b) { return $a <=> $b; }; $test = [ ['title' => 'hello', 'test' => 3], ['title' => 'goodbye', 'test' => 2], ['title' => 'something', 'test' => 4] ]; array_column($sort($test, $f), 'title'); // ['goodbye', 'hello', 'something']
贡献
如果我遗漏了您喜欢的任何组合器,请随时提交PR。如果您有任何使这些README更清晰的优秀想法,那将非常棒:尽管这些组合器对于函数式程序员来说并不陌生,但它们确实很复杂,需要很好地解释。所有帮助都备受感激:)