Добавление церковных цифр с использованием лямбда-функций в python

Я пытаюсь самостоятельно изучить Python и CS, используя онлайн-курс, основанный на SICP. Я понимаю основы церковных цифр, но у меня возникают проблемы с добавлением церковных цифр с использованием лямбда-функций в python.

Это мой код ниже для контекста:

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."""
    return lambda x: f(x)


def two(f):
    """Church numeral 2."""
    return lambda x: f(f(x))


def church_to_int(n):
    """Convert the Church numeral n to a Python integer.

    >>> church_to_int(zero)
    0    
    >>> church_to_int(one)
    1
    >>> church_to_int(two)
    2
    """
    return n(lambda x: x + 1)(0)


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

    >>> three = successor(two)
    >>> four = successor(three)
    >>> church_to_int(mul_church(two, three))
    6
    >>> church_to_int(mul_church(three, four))
    12
    """
    return lambda x: m(n(x))

Это функция add_church, с которой у меня возникли проблемы:

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
    """
    return lambda f: lambda x: m(f(x))(n(x))

Я пришел к выводу, что способ добавления церковных цифр состоит в том, чтобы каким-то образом сделать так, чтобы одна из функций в add_church(m, n) была входом или «x» в другой лямбда-функции. Однако я продолжаю получать ошибки, которые означают, что я не использую правильные аргументы в вызове функции.

Например, когда я звоню:

church_to_int(add_church(one, two))

Среди прочего я получаю сообщение об ошибке "int object not callable", а также безуспешно пробовал другие методы.

Я думаю, что есть что-то, чего я не вижу в лямбда-функциях, из-за чего у меня возникают проблемы с реализацией add_church. Я потратил некоторое время на выяснение этого, поэтому любая помощь, которая поможет мне найти ответ, будет очень признательна.


person Andrew    schedule 23.07.2014    source источник


Ответы (1)


Напомним, что кодирование Черча можно понимать как многократное применение функции к аргументу. Итак, чтобы добавить 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

В лямбда-форме удаление лишних скобок:

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))
person ecatmur    schedule 23.07.2014
comment
Ваш пример с использованием функций был действительно проницательным и прояснил много путаницы в понимании лямбда-функций, и я нашел его очень умным. На самом деле я собираюсь поиграть с переводом функций в лямбда-выражения, чтобы действительно понять это. Спасибо! - person Andrew; 23.07.2014