tarsana/functional

PHP 函数式编程库

2.2.2 2018-07-21 01:02 UTC

This package is auto-updated.

Last update: 2024-09-24 05:53:25 UTC


README

Build Status Coverage Status Scrutinizer Code Quality Donate Software License

PHP 函数式编程库。

目录

简介

这是什么?

这是一个 函数式编程 的 PHP 库。

为什么选择函数式编程?面向对象不够好吗?

这取决于你的需求。函数式编程(FP)和面向对象编程(OOP)非常不同。我个人喜欢函数式编程,因为代码更容易编写、测试和维护;即使它通常比等价的程序性或面向对象的代码运行得慢。

刚刚在 Google 上搜索并发现了许多 PHP 的函数式编程库。为什么你要写一个新的呢?

这个库受到了 Ramda 的启发,这是一个 JavaScript 的函数式编程库。Ramda 是在 underscorelodash 之后创建的,并且它具有比其他库更好的函数式 API。 这个讲座解释了如何做到这一点。所以我想要一个与 Ramda 具有相同哲学的库,支持旧版本的 PHP(从版本 5.4 开始)。

入门

您可以使用 composer 安装此库。

composer require tarsana/functional

然后您可以通过导入 Tarsana\Functional 命名空间来使用它。

use Tarsana\Functional as F;
// all functions are defined in this namespace

$incrementAll = F\map(F\plus(1));

$incrementAll([1, 2, 3]); //=> [2, 3, 4]

特性

此库的主要特性包括

  • Ramda 风格的函数式 API,具有 curry()__()

  • 包含 140+ 个测试用例的 390+ 个断言的 100+ 个函数。

  • 所有函数都默认是 curried 的。

  • 无依赖!

  • 支持自 5.4 版本的 PHP

  • 灵活的 Stream 类。

函数

函数被分组到模块中

为什么是类?这不是一个函数式库吗?

只要它们是 不可变 的并且有 纯方法,我们就可以使用类来定义类型和容器。将容器定义为类给我们一个流畅的 API 和优雅的代码。

在此库中定义的主要类是 Stream。它是一个不可变的数据容器,具有惰性评估和类型错误检测。它将允许你编写如下代码

<?php
require __DIR__ . '/vendor/autoload.php';

use Tarsana\Functional as F;
use Tarsana\Functional\Stream;

// Define new Stream operations
Stream::operation('contents', 'String -> String', 'file_get_contents');

$s = Stream::of('temp.txt') // initializing the Stream with the filename
    ->contents() // Reading the content of the file using the operation we defined
    ->regReplace('/[^a-zA-Z0-9 ]/', ' ') // removing non-alphanumeric chars
    ->split(' ') // Splitting text into words
    ->filter(F\notEq('')) // removing empty words
    ->map(F\lowerCase()) // makes all words in lower case
    ->reduce(function($words, $w) {
        return F\has($w, $words)
            ? F\update($w, F\plus(1), $words)
            : F\set($w, 1, $words);
    }, []); // transform the content to an array associating each word to occurences

print_r($s->result());

然后如果文件 temp.txt 包含

We can use classes to define Types and Containers as long as they are **immutable** and have **pure methods**. Defining a container as a class gives us a fluent API and elegant code.

上面的代码将输出

Array
(
    [we] => 1
    [can] => 1
    [use] => 1
    [classes] => 1
    [to] => 1
    [define] => 1
    [types] => 1
    [and] => 3
    [containers] => 1
    [as] => 3
    [long] => 1
    [they] => 1
    [are] => 1
    [immutable] => 1
    [have] => 1
    [pure] => 1
    [methods] => 1
    [defining] => 1
    [a] => 3
    [container] => 1
    [class] => 1
    [gives] => 1
    [us] => 1
    [fluent] => 1
    [api] => 1
    [elegant] => 1
    [code] => 1
)

点击此处了解更多关于 Stream 的信息

还有一个 Tarsana\Functional\Error 类,它只是扩展了默认的 Exception 类,并提供了一个静态方法 Error::of('msg') 来创建新错误,而无需使用 new 操作符。

测试

所有测试都在 tests 目录下。它们可以使用 phpunit 运行。

贡献

请考虑阅读 贡献指南,它将帮助您了解项目结构以及为什么我包括 build.phppackage.json 文件!

变更日志

版本 2.2.2

  • chunks 上修复了错误。

版本 2.2.1

  • 修复了 remove 上的 bug。

版本 2.2.0

  • 按照请求添加了 compose 函数 此处

  • 添加了 贡献指南

  • 109 个函数,152 个测试,包含 421 个断言。

版本 2.1.0

  • 提高库的效率。

  • 108 个函数,151 个测试,包含 420 个断言。

版本 2.0.0

  • 移除了依赖 cypresslab/php-curry

  • 新模块:对象和常用。

  • 108 个函数,143 个测试,包含 393 个断言。

  • 新构建脚本,用于生成文档和一些单元测试。

  • 重新编写了 Stream 类以支持自定义操作。现在 get() 被称为 result() 以避免与 get() 冲突。

版本 1.1.0

  • 修复 remove bug:使其成为柯里化。

版本 1.0.0

  • 包含 64 个函数 的 5 个模块(函数、操作符、字符串、列表、数学)。
  • Stream:一个懒数据容器