非常简单/乐趣工厂

流畅且高效地组合函数、方法和 lambda 表达式字符串

0.3.0 2019-10-01 22:23 UTC

This package is auto-updated.

Last update: 2024-09-29 05:15:00 UTC


README

你是否厌倦了输入 function($x) use($y) { return $z; } 这样的代码,而你只想得到一个简单的 lambda 表达式,或者链式调用几个属性访问或方法调用?你能否像使用 PHP 那样方便地组合函数,但又讨厌使用那些深度嵌套闭包并且不太符合 PHP 习惯的大型“函数式”库?

欢迎使用 乐趣工厂。只需 composer require dirtsimple/fun-factoryuse function dirtsimple\fun;,即可获得以下功能编程快捷方式

fun() 函数接受零个或多个 PHP 可调用函数(或 lambda 表达式字符串),返回这些参数的功能组合。字符串参数如果不是 PHP 函数或静态方法名,则假定是 PHP 表达式,并转换为接受 $_ 作为参数的 lambda 函数。(生成的闭包被缓存,因此重复调用如 fun('$_ * 2'),不会使用过多内存或浪费时间重新编译。)

fun() 返回的可调用对象支持链式属性/元素访问和方法调用,返回新的可调用对象,堆叠这些访问,使得增量组合功能管道变得容易。但由于 PHP 优化了递归,乐趣工厂将组合函数表示为要迭代的 opcode 数组,而不是递归到其中,与基于闭包的功能库相比,将函数调用开销和堆栈深度减半。

乐趣工厂的这种设计和其他方面都是为了使其他库能够向其客户提供 lambda 表达式和链式支持。如果你的 API 在提供的回调参数上调用 fun(),它将使您的客户能够传入 lambda 表达式以及标准 PHP 回调。

然后您可以组合或堆叠结果,或将可组合/可堆叠的结果返回给您的客户。(由于 fun() 是幂等的,并且对已经由它包装的东西调用它是一个快速的无操作,因此即使在有人一开始就传入 fun() 的情况下,也可以使用它。)

其他 API

但是等等,还有更多!现在在您的代码中添加 use dirtsimple\fun;,您还将免费获得这些出色的静态方法

组合和绑定

fun::_(...$callables)

返回一个 管道 组合的 $callables,其中每个可调用的结果都传递到链中的下一个。例如,fun::_('array_reverse', 'array_flip') 返回一个可调用对象,它在其输入上调用 array_reverse(),然后在其结果上调用 array_flip()

此方法的行为与 fun() 完全相同,包括对 lambda 字符串的支持,但它的参数调用顺序相反。也就是说,fun($f, $g) 等价于 fun::_($g, $f) 等价于 function ($x) { return $f( $g( $x ) ); }

fun::bind($callable, ...$args)

返回一个 fun(),当调用时,以 $x 作为参数返回 $callable(...$args, $x)。(也就是说,在 $callable 之后的所有参数都会先传入。)请注意,fun() 对象恰好接受一个参数(如果省略,默认为 null),因此 $callable() 总是在 $args 之后接收一个参数。

$callable 必须 是 PHP 可调用函数(不是 lambda 表达式字符串),并在绑定时进行检查其有效性。(这可能导致自动加载,如果它命名了一个静态方法。)

(请注意,fun() 对象本身只接受一个参数,因此将 fun() 作为 bind()$callable 参数传递,实际上使其始终传递 $args 的第一个元素,而不是实际给出的任何参数。)

fun::tap(...$callables)

返回一个 fun(),它将 fun(...$callables) 应用于其参数,但丢弃返回值并返回原始参数。这在创建副作用时很有用,大致相当于

$f = fun(...$callables);
function ($_) use ($f) { $f($_); return $_; }

只是返回一个 fun() 而不是闭包。

fun::val($value)

返回一个可调用的函数,该函数返回 $value。这是 function() use ($value) { return $value; } 的简写。

条件语句

fun::when($cond, $ifTrue, $ifFalse='$_')

返回一个与 function($_) { return $cond($_) ? $ifTrue($_) : $ifFalse($_); } 大致等价的 fun(),但三个参数都可以是 lambda 表达式字符串,以及 PHP 可调用对象。

fun::unless($cond, $ifFalse, $ifTrue='$_')

fun::when() 相同,但参数顺序相反。

结构转换

fun::transform($schema, $input=null, $out=array(), $reducer=null)

根据 $schema 转换 $input。模式必须是数组或可迭代的可调用对象。每个可调用对象在 $input 上调用的结果将放置在 $out 的对应键中,然后返回。

可以通过传递 $reducer 进一步自定义此函数的行为:一个接受四个参数的可调用对象:当前的 $out 值、一个 $key、原始的 $input 以及在 $schema[$key] 中找到的可调用对象。然后,将还原器的返回值反馈到下一次调用或在没有更多条目在模式中时返回。默认的还原器如下所示

function ($out, $key, $fn, $input) {
    $out[$key] = $fun($input);
    return $out;
}

使用适当的 $out$reducer,您可以设置属性、调用方法、转换键、跳过键、过滤结果等。

fun::schema($schema)

这是将给定模式与 fun::transform 柔性组合的快捷方式;即,它返回一个函数,给定一个输入,使用给定的模式对其进行转换。($out$reducer 转换参数可以作为返回函数的第二个和第三个参数传递。)

其他函数

fun::is_callable_name($string)

如果 $string 是一个语法上有效的 PHP 可调用对象,则返回 true。即,如果 $string 与一个可能命名空间的函数或静态方法的正则表达式匹配。不检查函数、类或方法的存在,只检查语法。fun() 在内部使用此来区分可调用对象和 lambda 表达式,同时延迟类加载或函数查找,直到实际调用结果对象。

API 版本兼容性

请注意,此库的 API 仅限于本 README 中记录的内容,而不是在类中公开的内容或由规范测试的内容!此处未明确记录的内容可能在甚至 次要 版本之间发生变化。(特别是,请注意,每当此文档提到返回“可调用对象”时,您不应假设将返回什么 类型 的可调用对象,除了 PHP is_callable() 将对它返回 true 之外。)