PHP函数式编程初探之“三板斧”:过滤、映射、归约

函数式编程是一种不同于对象式编程的思想,虽然PHP并不是天生就属于函数式编程的语言,也不擅长该领域,但这里希望通过PHP对函数式支持实现,加深对函数式编程的范式和思想。

 

PHP本身的语法、语义不能完全很好地支持函数式编程,因为这里我需要通过实现封装类库来完成PHP对函数式编程的支持。

 

两个示例的最终效果

先来看下最终的效果:假设我们需要计算1到5之间的偶数之和的两倍,那么:

$fun = new Functional_Lite(range(1, 5));


$rs = $fun->filter(function ($x) { return $x % 2 == 0;})
            ->map(function ($x) {return $x * 2;})
            ->reduce(function ($x, $y) { return $x + $y;}, 0);

var_dump($rs); // 2 * 2 + 4 * 2 = 12

 

如果想更简短一点,可以这样使用字符串表达式:

$fun = new Functional_Lite(range(1, 5));


$rs = $fun->filter('$it % 2 == 0')
            ->map('$it * 2')
            ->reduce('$it_1 + $it_2', 0);

var_dump($rs); // 2 * 2 + 4 * 2 = 12

注意这里使用了 $it 来表示每次迭代的元素;对于reduce操作,使用了$it_1、$it_2分别表示第一个元素、第二个元素。

 

除了对数值进行操作,我们也希望可以对字符串或其他类型的集合进行操作,假设需要过滤一个字符的单词,然后把剩下的单词转大写,再用空格拼接起来。那么:

$fun = new Functional_Lite(array('dogstar', 'x', 'love', 'y', 'yoyo', '!!'));

$rs = $fun->filter(function ($x) { return strlen($x) > 1;})
            ->map(function ($x) { return strtoupper($x);})
            ->reduce(function ($x, $y) { return $x . ' ' . $y;}, 'RS:');

var_dump($rs); // RS: DOGSTAR LOVE YOYO !!

在上面,对于最后的结果,我们在累加量初始了“RS:”,所以最后的结果里有“RS:”的前缀。这里的一个问题是,还没想好如何更好地处理初始值。

 

同样,使用字符串表达式,可以简化上面的处理以达到同样的效果:

$rs = $fun->filter('strlen($it) > 1')
            ->map('strtoupper($it)')
            ->reduce('$it_1 . " " . $it_2', 'RS:');

 

至此,通过上面两个示例,可以看出都使用了函数式编程的“三板斧”:过滤、映射、归约。

对于这“三板斧”的定义和作用,这里不作过多的赘述。

 

类库实现

上面,我们封装了Functional_Lite这个类,以便更好的实现函数式编程。为了构造一个函数式的类库,可以传入一个集合,目前只支持数组,且会忽略索引。具体的源代码,可见GIT仓库:http://git.oschina.net/dogstar/functional_php

 

小结

当然,这里只是简单地实现了一下函数式编程最主要的三个操作:过滤、映射、归约。但离函数式编程的道路还很遥远,比如柯里化、部分施用、偏函数、Either类、Opeion类、值不可变。而且还有很多在PHP是明显很难实现的,如上下文的处理。

Anyway,这只是一个小开始,只是作为自己的一个小结。

 

转载于:https://my.oschina.net/dogstar/blog/791051

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值