Python 函数式复合和PyMonad*运算符

Python 函数式复合和PyMonad*运算符,柯里化函数的一个重要价值是可以通过函数式复合来组合函数。第5章和第11章介绍了函数式复合。

创建了一个柯里化函数后,就可以更轻松地通过函数式复合来创建新的、更复杂的柯里化函数了。例如PyMonad包定义了*运算符来复合两个函数。为了解释这个运算符的工作原理,下面定义两个用于复合的柯里化函数。首先定义一个用于计算乘积的函数,然后定义一个用于计算特定范围值的函数。

用于计算乘积的第一个函数如下所示:

import  operator
prod = myreduce(operator.mul)

该函数基于此前定义的柯里化函数myreduce()。它使用operator.mul()函数来计算一个可迭代对象的乘法归约,换言之,将乘积定义为了一组序列的乘法归约。

用于生成一系列数值的第二个柯里化函数如下所示:

@curry
def alt_range(n):
    if n == 0:
        return range(1, 2)  # Only the value [1]
    elif n % 2 == 0:
        return range(2, n+1, 2)
    else:
        return range(1, n+1, 2)

函数alt_range()的结果可以是偶数也可以是奇数。如果n是奇数,则结果只包含到n(含)的奇数值;如果n是偶数,则结果只包含到n的偶数值。这种序列对于实现半阶乘函数或双阶乘函数 n!! 尤为重要。

下面介绍如何将prod()函数和alt_range()函数组合成一个新的柯里化函数。

>>> semi_fact = prod * alt_range
>>> semi_fact(9)
945

这里PyMonad的*运算符将两个函数组合成了复合函数semi_fact。它对参数使用函数alt_range(),随后prod()函数会使用alt_range函数的结果。
使用PyMonad的*运算符等同于创建一个新的匿名函数对象。

semi_fact = lambda x: prod(alt_range(x))`

与创建一个新的匿名函数对象相比,柯里化函数的复合涉及的语法要少一些。
理想情况下,我们希望能如下所示使用函数式复合和柯里化函数:

sumwhile = sum * takewhile(lambda x: x > 1E-7)

这样就可以定义一个适用于无穷序列的sum()函数版本,并且在满足阈值条件时停止生成新的值。然而由于PyMonad库处理无穷迭代对象的能力似乎不及处理内部List对象的能力,因此这种做法实际上不起作用。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程