Python 使用柯里化的高阶函数

Python 使用柯里化的高阶函数,尽管可以使用普通函数表现柯里化,但只有将柯里化用于高阶函数时,其价值才会真正显现。在理想情况下,functools.reduce()函数是可柯里化的,因此可以如下操作:

sum = reduce(operator.add)
prod = reduce(operator.mul)

然而这样做并不起作用。内置的reduce()函数不能经由PyMonad库实现柯里化,因此上面的例子实际上无法正常运作。但是,如果自定义了reduce()函数,那么就可以如前所示对其进行柯里化了。

下面是一个自定义的reduce()函数,可以如前所述使用它:

from collections.abc import Sequence
from pymonad import curry

@curry
def myreduce(function, iterable_or_sequence):
    if isinstance(iterable_or_sequence, Sequence):
        iterator= iter(iterable_or_sequence)
    else:
        iterator= iterable_or_sequence
    s = next(iterator)
    for v in iterator:
        s = function(s,v)
    return s

函数myreduce()的行为和内置的reduce()函数类似。函数myreduce()适用于可迭代对象或者序列对象。对于给定序列,可以创建一个迭代器,而对于给定的可迭代对象,可以直接使用它。使用迭代器中的第一项来初始化结果。将该函数应用于进行中的求和(或乘积)以及随后的每一项。

还可以封装内置的reduce()函数来创建一个可柯里化的版本。只需两行代码便可以实现,这留给读者作为练习。

由于myreduce()函数是一个柯里化函数,因此接下来可以基于该高阶函数创建函数。

>>> from operator import add
>>> sum = myreduce(add)
>>> sum([1,2,3])
6
>>> max = myreduce(lambda x,y: x if x > y else y)
>>> max([2,5,3])
5

我们通过应用于add运算符的柯里化归约自定义了sum()函数,还使用选取两个值中较大值的匿名函数对象自定义了默认的max()函数。

由于柯里化关注位置参数,因此无法以这种方式简单地创建出max()函数的更通用的形式。如果使用key=关键字参数,那么为了实现函数式编程简洁明了的整体目标,会在技术上带来极大的复杂性。

为了创建一个更通用的max()函数,需要摆脱函数max()min()sorted()等依赖的key=关键字参数范式。必须像filter()map()reduce()函数那样以高阶函数作为第一个参数。还可以创建一个更统一的高阶柯里化函数库,这些函数将完全依赖位置参数。首先以高阶函数为参数,这样自定义的柯里化max(function, iterable)方法就能遵循map()filter()functools.reduce()等函数设置的模式了。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程