daveross/functional-programming-utils

PHP 5.4+ 的函数式编程工具

4.0.0 2016-05-23 18:59 UTC

This package is not auto-updated.

Last update: 2024-09-11 23:13:43 UTC


README

Latest Stable Version Total Downloads Latest Unstable Version License Build Status Scrutinizer Code Quality

PHP 5.4+ 的函数式编程工具

目录

安装

使用 composer

在您的 composer.json 文件中添加 functional-programming-utils 的 require 语句,然后运行 composer installphp composer.phar install

{
    "require": {
        "daveross/functional-programming-utils": "~4.0"
    }
}

手动安装

包括 src 目录中的所有文件,或根据需要包括单个文件

<?php
include 'path/to/functional-programming-utils/src/compose.php';
include 'path/to/functional-programming-utils/src/curry.php';
include 'path/to/functional-programming-utils/src/math.php';
include 'path/to/functional-programming-utils/src/memoize.php';
include 'path/to/functional-programming-utils/src/prop.php';
include 'path/to/functional-programming-utils/src/Monads/Monad.php';
include 'path/to/functional-programming-utils/src/Monads/Just.php';
include 'path/to/functional-programming-utils/src/Monads/Maybe.php';
include 'path/to/functional-programming-utils/src/Monads/Either.php';
include 'path/to/functional-programming-utils/src/Monads/Left.php';
include 'path/to/functional-programming-utils/src/Monads/Right.php';

许可证

MIT

查看 为什么我贡献开源软件.

买我一杯咖啡

贡献

欢迎提交拉取请求。单元测试受到鼓励但不是必需的。

进一步阅读和建议观看

Simon Holywell 在 2014 年 2 月 PHP Hampshire 上的 Functional PHP 演讲

PHP Hampshire Feb 2014: Functional PHP

PHP 5.6+ 用户注意

从 PHP 5.6 开始,您可以在文件顶部使用 use function 来引用该函数,而无需包括其整个名称,包括命名空间。我鼓励您尝试一下。

use function DaveRoss\FunctionalProgrammingUtils\add as add;
$x = add( 5, 5 ); // 10

功能

数学函数

add

添加两个值

$x = DaveRoss\FunctionalProgrammingUtils\add( 5, 5 ); // 10

subtract

减去两个值

$x = DaveRoss\FunctionalProgrammingUtils\subtract( 10, 5 ); // 5

multiply

乘以两个数字

$x = DaveRoss\FunctionalProgrammingUtils\multiply( 5, 5 ); // 25

divide

除以两个数字

$x = DaveRoss\FunctionalProgrammingUtils\divide( 25, 5 ); // 5

modulus

计算除法后的余数

$x = DaveRoss\FunctionalProgrammingUtils\modulus( 13, 5 ); // 3

inverse

取反一个数字

$x = DaveRoss\FunctionalProgrammingUtils\inverse( 5 ); // -5

truthy

使用标准 PHP 规则检查值是否评估为 true

$x = DaveRoss\FunctionalProgrammingUtils\truthy( 5 ); // true
$x = DaveRoss\FunctionalProgrammingUtils\truthy( 0 ); // false

true

检查值是否为布尔值 true

$x = DaveRoss\FunctionalProgrammingUtils\true( true ); // true
$x = DaveRoss\FunctionalProgrammingUtils\true( 5 ); // false

falsy

使用标准 PHP 规则检查值是否评估为 false

$x = DaveRoss\FunctionalProgrammingUtils\falsy( 0 ); // true
$x = DaveRoss\FunctionalProgrammingUtils\falsy( 5 ); // false

false

检查值是否为布尔值 false

$x = DaveRoss\FunctionalProgrammingUtils\false( false ); // true
$x = DaveRoss\FunctionalProgrammingUtils\false( 0 ); // false

default_value

返回一个值,如果值为 null,则返回默认值

$x = DaveRoss\FunctionalProgrammingUtils\default_value( 5, 10); // 10
$x = DaveRoss\FunctionalProgrammingUtils\default_value( 5, null); // 5

属性访问

array_prop

根据相应的键从数组中返回一个值,如果键不存在于数组中,则返回 null

$a = array( 'hello' => 'world', 'a' => 'b' );
$x = DaveRoss\FunctionalProgrammingUtils\array_prop( $a, 'hello'); // 'world'
$x = DaveRoss\FunctionalProgrammingUtils\array_prop( $a, 'test'); // null

object_prop

根据相应的属性名从对象中返回一个值,如果属性不存在于对象中,则返回 null

$o = new stdClass();
$o->hello = 'world';
$o->a = 'b';
$x = DaveRoss\FunctionalProgrammingUtils\object_prop( $o, 'hello'); // 'world'
$x = DaveRoss\FunctionalProgrammingUtils\object_prop( $o, 'test'); // null

prop

根据适当的情况调用 array_propobject_prop

$a = array( 'hello' => 'world', 'a' => 'b' );

$x = DaveRoss\FunctionalProgrammingUtils\prop( $a, 'hello'); // 'world'
$x = DaveRoss\FunctionalProgrammingUtils\prop( $a, 'test'); // null

$o = new stdClass();
$o->hello = 'world';
$o->a = 'b';

$x = DaveRoss\FunctionalProgrammingUtils\prop( $o, 'hello'); // 'world'
$x = DaveRoss\FunctionalProgrammingUtils\prop( $o, 'test'); // null

缓存

memoize

在一个层中包装一个函数,该层存储函数针对每次调用的参数集的返回值,因此无需再次调用该函数

$f = DaveRoss\FunctionalProgrammingUtils\memoize(function($a) { return $a; });
$x = $f(5); // 5
$x = $f(5); // 5 again, but the function didn't need to be called a second time

柯里化

查看 柯里化或部分应用?部分应用和柯里化的区别 了解这些函数之间的区别。

partially_apply

部分应用 一个函数。给定一个接受多个参数的函数,返回一个已知第一个参数的函数。

$add_five = DaveRoss\FunctionalProgrammingUtils\partially_apply( 'DaveRoss\FunctionalProgrammingUtils\add', 5 );
$x = $add_five( 5 ); // 10

partially_apply_right

部分应用一个函数。给定一个接收多个参数的函数,返回一个已经知道最后一个参数的函数。

$divide_by_five = DaveRoss\FunctionalProgrammingUtils\partially_apply_right( 'DaveRoss\FunctionalProgrammingUtils\divide', 5 );
$x = $divide_by_five( 25 ); // 5

curry

柯里化一个函数。给定一个接收多个参数的函数,将其应用于一个参数,并返回一个接收下一个参数的函数,直到所有必需的参数都提供。

  function add_three_integers($a, $b, $c) {
  		return intval( $a ) + intval( $b ) + intval( $c );
  }

  $fn = DaveRoss\FunctionalProgrammingUtils\curry( 'add_three_integers' , 1 );
  $fn2 = $fn( 2 );
  $x = $fn2( 3 ); // 6

组合

compose

创建一个新的函数,该函数由一系列每个函数接收一个参数的函数组成。当调用新函数时,从右到左调用这些函数,处理上一个函数的结果。

$backwards_and_uppercase = DaveRoss\FunctionalProgrammingUtils\compose( 'str_reverse', 'strtoupper' );
$x = $backwards_and_uppercase( 'dlrow olleh' ); // HELLO WORLD

单子

Monad

Monad的抽象父类。Monad是一个封装单个值并实现function map(callable $f)的类。Monad::map()返回另一个封装函数返回值的Monad。参见Just Monad。

Just

Just Monad“只是”封装一个值并将函数映射到它。

$x = new Just( 5 );
$y = $x->map( function( $a ) { return $a * 5; } ); // Just(25)

Maybe

Maybe Monad识别它是否持有null值,并在将函数映射到它时返回Maybe( null )。否则,它像Just Monad一样行为。

$x = new Maybe( 5 );
$y = $x->map( function( $a ) { return $a * 5; } ); // Maybe(25)

$a = new Maybe( null );
$b = $a->map( function( $a ) { return $a * 5; } ); // Maybe(null)

maybe函数

可以用来从Maybe Monad中提取值。

$x = new Maybe( 5 );
$y = maybe(null, function( $a ) { return $a * 5; }, $x); // 25

Either

为了实现条件语句,可以将函数定义为返回要么一个值,要么另一个值。这用Either Monad及其子类LeftRight来表示。

Left

Left Monad封装来自不成功函数调用的错误值。

$f = function($a) {
	return ( $a < 10 ) : Left::of( 'too low' ) : Right::of( $a + 1 );
}

$x = $f( 15 ); // Right( 16 )
$y = $f( 5 ); // Left( "too low" )
Right

Right Monad封装成功函数调用的结果。

$f = function($a) {
	return ( $a < 10 ) : Left::of( 'too low' ) : Right::of( $a + 1 );
}

$x = $f( 15 ); // Right( 16 )
$y = $f( 5 ); // Left( "too low" )

either函数

可以用来从Left Monad或Right Monad中提取值。

$x = Left::of( 5 );
$y = Right::of( 7 );

$left_handler = function( $a ) { return $a * 2; };
$right_handler = function( $a ) { return $a * 3; };

$a = either($left_handler, $right_handler, $x); // 10
$b = either($left_handler, $right_handler, $y); // 21

版本历史

  • 2015-08-18   1.0.0   初始发布
  • 2015-12-16   2.0.0   修复了柯里化与部分应用语义
  • 2016-01-30   3.0.0   将"Functor"改为"Monad",这更准确
  • 2016-05-23   4.0.0   Scrutinizer CI集成,PSR-2合规性