您展示的问题也可以通过这种方式解决。
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
接受另一个函数,当给定参数 ( a
, b
) 时,返回c
,其中c
可能是a
orb
或其他东西。f
然后返回 的值c
。
多嘴啊!
另一种思考方式是,返回的函数f
( ((a, b) -> c) -> c
)cons
用于转发a
和转发b
给任何想要对 a 进行操作的运算符(或映射函数)cons
。此运算符返回c
. f
然后 simple 返回此映射函数返回的任何内容,恰好是c
.
现在不用担心是什么c
。只需将其视为将函数应用于 a 的结果cons
。
car::(((a, b) -> a) -> a) -> a
car
定义一个从(a,b)
to的可能映射,并返回使用此映射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
返回 a 的第一个元素cons
。在这种情况下,由于cons(3,4)
返回一个函数 ( f
) 并且此函数被传递给car
,然后car
将向此函数提供另一个函数,该函数选择它的第一个参数,3
在这种情况下。这3
是现在的结果car(cons(3,4)
。
我希望这能解决问题。