关于嵌套lambda表达式的理解

在UCB CS 61A的Homework 02中,有这样一个问题:
Question 4: Church numerals

def zero(f):
    return lambda x: x

def successor(n):
    return lambda f: lambda x: f(n(f)(x))

def one(f):
    """Church numeral 1: same as successor(zero)"""
    "*** YOUR CODE HERE ***"
    return lambda x: x

def two(f):
    """Church numeral 2: same as successor(successor(zero))"""
    "*** YOUR CODE HERE ***"
    return lambda x: f(x)

three = successor(two)

难以理解的那段代码为:

def successor(n):
    return lambda f: lambda x: f(n(f)(x))

successor函数使用 lambda 返回匿名函数。这很难阅读,所以我们可以使用一个命名函数替换它。

def successor(n):
    def inner_function_one(f):
        def inner_function_two(x):
            return f(n(f)(x))
        return inner_function_two
    return inner_function_one

所以现在我们已经分解了原函数,可以看到successor返回一个函数,而该函数又返回另一个函数,该函数返回…。 f(n(f)(x)) 让人很难阅读,其含义为函数f被参数 n(f)(x)调用,而n(f)返回一个函数传递参数x。让我们使用一些更具描述性的变量名称来查看此处发生的情况。

def successor(first_function):
    def inner_function_one(second_function):
        def inner_function_two(arg):
            return second_function(first_function(second_function)(arg))
            # Equivalent to something like
            #     return second_function(returned_function(arg))
            # where returned_function is the result of 
            #     first_function(second_function)
        return inner_function_two
    return inner_function_one

接下来题目又问道:

def add_church(m, n):
    """Return the Church numeral for m + n, for Church numerals m and n.

    >>> church_to_int(add_church(two, three))
    5
    """
    "*** YOUR CODE HERE ***"
    return lambda f: lambda x: m(f)(n(f)(x))

Church 编码可以理解为将函数重复应用于某个参数。所以要add m + n,我们需要将函数 f 应用到参数 x m + n 次,或者等效地应用它 n 次,然后应用它 m 次:

def add_church(m, n):
    def m_plus_n(f):
        def f_repeated_m_plus_n_times(x)                # f ** (m + n)
            intermediate_result = (n(f))(x)             # (f ** n) (x)
            final_result = (m(f))(intermediate_result)  # (f ** m) ((f ** n) (x))
            return final_result
        return f_repeated_m_plus_n_times
    return m_plus_n

使用 lambda 形式,删除多余的括号:

def add_church(m, n):
    """Return the Church numeral for m + n, for Church numerals m and n.
    >>> three = successor(two)
    >>> church_to_int(add_church(two, three))
    5
    """
    lambda f: lambda x: m(f)(n(f)(x))

猜你喜欢

转载自blog.csdn.net/wilde123/article/details/125446253