martinezdelariva/functional

函数式编程的语法增强运算符

v0.4-alpha 2017-06-18 18:21 UTC

This package is not auto-updated.

Last update: 2024-09-29 02:03:44 UTC


README

Build Status

函数式编程的语法增强运算符

  • 柯里化
  • 管道
  • 模式匹配
  • 折叠

目前有计划将 柯里化管道运算符 作为 PHP 函数包含进来。同时,您也可以为了娱乐而使用这个库!

备注

  • curry 不会知道一个可选参数的函数是否没有被提供。所以,只有当所有参数都给出时,curry 才会运行被柯里化的函数。
  • 柯里化部分函数应用 对比 维基百科

安装

使用 Composer 安装

composer require martinezdelariva/functional

用法

作为单个函数导入

   namespace Foo;

   use function Martinezdelariva\Functional\pipe;

   class Bar
   {
        public function baz()
        {
            pipe(
                'trim',
                'ucwords'
            )(' string ');
        }
   }

导入命名空间

   namespace Foo;

   use Martinezdelariva\Functional as F;

   class Bar
   {
        public function baz()
        {
            F\pipe(
                'trim',
                'ucwords'
            )(' string ');
        }
   }

函数

curry

function sum(int $one, int $two, int $three) : int {
    return $one + $two + $three;
};

// curry firsts params
$sum3 = curry('sum', 1, 2);
$sum3(3); // output: 6
$sum3(5); // output: 8

// curry whole function
$sum  = curry('sum');
$sum1 = $sum(1);
$sum1(2, 3); // output: 6

// curry with all params given
curry(sum::class, 1, 2, 3); // output: 6

curry_left

curry_leftcurry 的别名。

curry_right

function minus(int $one, int $two) : int {
    return $one - $two;
};

$minus1 = curry_right('minus');
echo $minus1(1)(4); // output: 3

match

$patterns = [
    'a'              => "It's an 'a'",
    'foo'            => function ($input, $other) {
                            return "$input::$other";
                        },
    'is_int'         => function ($input) {
                            return $input + 1;
                        },
    \stdClass::class => "It's an 'stdClass'",
    _                => "Default"
];

// provinding params
match($patterns, 'a');          // output: "It's an 'a'"

// provinding one by one param due `match` is curried
$match = match($patterns);
$match(5);                      // output: 6
$match(new \stdClass());        // output: "It's an 'stdClass'"
$match('unknown');              // output: "Default"

// provinding param to callables with more params
$match('foo')('bar');           // output: foo::bar

管道

$format = pipe(
    'trim',
    'ucwords',
    function (string $names) : string {
        return implode(', ', explode(' ', $names));
    }
);

$format('  john mary andre'); // output: John, Mary, Andre

折叠

// example: using fold to sum integers
$sum = fold(function($item, $carry) {
   return $item + $carry;
}, 0);
$sum([1, 2, 3, 4]); // output 10

// example: dynamically changing the fold function
$match = match([
   'is_string'  =>  function($item, $carry) {
                        return $carry.$item;
                    },
   'is_int'     =>  function($item, $carry) {
                        return "$carry{X}";
                    },
]);

fold($match, '', ['a', 'b', 'c', 2, 'd', 'e']);  // output "abc{X}de"