Таким образом можно решить и указанную вами проблему.
def cons(a, b):
return (a,b)
def car(pair):
return pair[0]
def cdr(pair):
return pair[1]
Вот как вы будете его использовать:
lst = cons(1,cons(2,3))
# Get the first element of lst
print(car(lst))
# Get the second element of lst
print(car(cdr(lst)))
# Get the last element of lst
print(cdr(cdr(lst)))
Вывод:
1
2
3
Я показываю это только для того, чтобы вы могли увидеть, что есть несколько способов решить эту проблему, и способ, который вы обнаружили, очень редко применяется в python. Любой, кто думает решить эту проблему на Python, в 99% случаев будет делать это так, как я показал здесь.
Теперь к твоей проблеме.
def cons(a, b):
def pair(f):
return f(a, b)
return pair
def car(f):
def pair(a,b):
return a
return f(pair)
def cdr(f):
def pair(a, b):
return b
return f(pair)
Сначала давайте поговорим об этих функциях, используя нотацию некоторых функций haskell, чтобы вы могли увидеть полный тип этих функций:
cons::(a, b) -> (((a, b) -> c) -> c)
cons
- это функция, которая принимает два параметра a
и b
, затем она возвращает функцию f
, которая принимает другую функцию, которая при заданных параметрах (_10 _, _ 11_) возвращает c
, где c
может быть a
или b
, или что-то еще. f
затем возвращает значение c
.
Какой полный рот!
Другой способ представить это - то, что функция f
(((a, b) -> c) -> c
), возвращаемая cons
, используется для пересылки a
и b
любому оператору (или функции сопоставления), который хочет воздействовать на cons
. Этот оператор возвращает c
. f
, тогда simple возвращает все, что возвращает эта функция сопоставления, что оказывается c
.
А пока не беспокойтесь, что такое c
. Подумайте об этом как о результате применения функции к cons
.
car::(((a, b) -> a) -> a) -> a
car
определяет возможное отображение от (a,b)
к c
и возвращает значение вызова f
с этим отображением.
car
принимает функцию f
, которая хочет сопоставить вход (a,b)
с некоторым выходом c
. В этом случае car
определяет отображение как (a, b) -> a
, что означает, что любая функция f
, переданная в car
, вернет первый аргумент (a,b)
, который равен просто a
. И это то, что car
вернет.
cdr::(((a, b) -> b) -> b) -> b
Подобно car
, но отображение, определенное cdr
, возвращает b
вместо a
.
Обратите внимание, насколько входные данные для cdr
и car
похожи на функцию (f
), возвращаемую cons
? Вот почему я просто назвал их входы f
Теперь отвечу на некоторые из ваших вопросов:
cdr(cons(3, 4))
: в каком порядке оцениваются эти две функции? Обычно я думаю, что сначала оцениваются cons(3, 4)
, но в данном случае это не имеет смысла, потому что cons(3, 4)
возвращает функцию, в которой аргументы 3 и 4 интегрированы, поэтому нет возможности выделить аргументы.
В свете объяснения, которое я дал выше, функция, возвращаемая из cons
, точно того же типа, что и функция, ожидаемая cdr
. Теперь все, что нужно сделать cdr
, - это предоставить функцию сопоставления f
и вернуть все, что возвращает f
.
Мне кажется, что car(f)
возвращает функцию, так как же cons(3, 4)
вернуть 3
? ИЗМЕНИТЬ: опечатка, должно быть car(cons(3, 4))
вместо cons(3, 4)
car(f)
не обязательно возвращает функцию. См. Подписи типов выше. Он просто возвращает то, что возвращает f
, и если это будет функция, то это то, что он вернет функцией.
Обычно car
возвращает первый элемент cons
. В этом случае, поскольку cons(3,4)
возвращает функцию (f
) и эта функция передается в car
, тогда car
предоставит этой функции другую функцию, которая выбирает первый из своих аргументов, которым в данном случае является 3
. Этот 3
теперь результат car(cons(3,4)
.
Надеюсь, это проясняет ситуацию.
person
smac89
schedule
25.09.2020
cons(3, 4)
возвращает функцию. Обратите внимание на имя параметраcdr
и его использование. То же самое и сcar
. - person Carcigenicate   schedule 24.09.2020pair()
запоминает значения параметров внешней функции. - person Barmar   schedule 24.09.2020