Recursion Little Schemer:编写只支持长度为≤;2.
在《小模式者》一书中,我们发现这个函数只支持长度小于或等于1的列表: 我想一步一步地学习,并想编写一个类似的函数,它只支持长度小于或等于2的列表 请不要通过提供以下代码来回答此问题:Recursion Little Schemer:编写只支持长度为≤;2.,recursion,scheme,y-combinator,the-little-schemer,anonymous-recursion,Recursion,Scheme,Y Combinator,The Little Schemer,Anonymous Recursion,在《小模式者》一书中,我们发现这个函数只支持长度小于或等于1的列表: 我想一步一步地学习,并想编写一个类似的函数,它只支持长度小于或等于2的列表 请不要通过提供以下代码来回答此问题: (((lambda (mk-length) ; B. (mk-length mk-length)) (lambda (mk-length) (lambda (l) (cond
(((lambda (mk-length) ; B.
(mk-length mk-length))
(lambda (mk-length)
(lambda (l)
(cond
((null? l) 0 )
(else (add1((mk-length mk-length) (cdr l))))))))
'(a b c d))
因为这个函数支持任何长度
我已经知道如何编写这样的函数:
(((lambda (mk-length) ; C.
(mk-length
(mk-length (mk-length eternity))))
(lambda (length)
(lambda (l)
(cond
((null? l) 0)
(else (add1 (length (cdr l))))))))
'(1 2)) ;;
为了实现我的目标。但这段代码与第一个代码片段相差一步多
也许,我不应该改变:
(lambda (mk-length) ; D.
(mk-length mk-length)
Lisp中的列表(Scheme、Common Lisp等)由cons单元格和特殊(空列表)组成。无论何时,只要你有一个列表,它是:
- 空列表()
- cons单元(也称为对),其中对的car是列表的第一个元素,对的cdr是列表的其余部分
- 空列表的结果是什么
- 列表其余部分的结果是什么?如何将其转化为整个列表的结果
- 空列表的长度为0
- 当列表其余部分的长度为n时,整个列表的长度为n+1李>
(((lambda (mk-length)
(mk-length mk-length))
(lambda (mk-length)
(lambda (l)
(cond
((null? l ) 0)
(else 1)))))
这对于长度为0的列表和长度为1的列表都有效,对于所有其他列表都不正确,但对于所有其他列表都返回1。除非你改变递归的结构,我认为这是你能做的最好的了。如果您愿意更改递归的结构,可以执行以下操作:
但你真的不应该采用这种方法,因为现在你在三种不同的情况下处理列表,而不是两种,这(几乎)永远都不是你想要做的
Python的翻译
这种想法可以用python或其他过程语言重写吗?仍然很难想象递归中自动创建的乐趣
同样的原理也适用于Python或任何支持高阶函数的语言。Python中更惯用的做法是在本地定义函数,然后调用它,而不是直接调用lambda表达式,因此这对您来说可能更具可读性:
def长度(l):
def驱动程序(递归):
“返回调用自身的'recurse'的结果。”
返回递归(recurse);
def ZeroForemptylStorelOnePlusResult(递归):
“”“返回一个函数,如果其输入为
空列表,否则返回1加上任何调用
`recurse(recurse)`返回列表的尾部。”“”
def长度(l):
“”“如果l是空列表,则返回0,加1
“(recurse(recurse))(l)”的结果为“否则”
如果l=[]:
返回0;
其他:
_,*rest=l
返回1+(递归(递归))(其余)
返回长度
返回(驱动程序(ZeroForeMptylStorelOnePlusRecreat))(l)
TL;DR:(mk length A)
(在cond
表单中)计算长度为0的列表的长度
函数,并将使用(A)
计算用于参数列表尾部的长度
函数(即(cdr…
)的结果
您的第一个代码段(
;A.
)仅适用于长度为0和1的列表。要使其也适用于2,请更换
(mk-length eternity) ; length≤1
我们可以看到(mk length…
在处的结果;(2)
用于处理(cdr l)
,而参数
用于处的mk length
;(2) 处理(cddr l)
时,
将替换该调用中的mk length
如果使用了(mk length-eventhesis)
(与第一个代码一样),(cdr l)
处理正常,但((eventhesis-eventhesis)(cddr l))
自然会失败
如果使用了(mk length(lambda(x)(mk length externature))
,(cdr l)
处理正常,然后((lambda(x)(mk length externature))(lambda(x)(mk length externature))=(mk length externature)
用于处理(cddr l)
,这也是正常的(因此,长度2处理正确),然后((永恒)(cdddr l))
自然失效(长度为3及以上)
因此,要处理多达三个元素的列表
((mk-length ; (2) ; length≤3
(lambda (x) (mk-length
(lambda (x) (mk-length eternity)))) )
可用于:
(define (eternity x) (- 1)) ; to get an error instead of looping
(((lambda (mk-length)
(mk-length mk-length))
(lambda (mk-length)
(lambda (l)
(cond
((null? l ) 0)
(else (add1 ((mk-length ; (2) ; length≤3
(lambda (x) (mk-length
(lambda (x) (mk-length eternity)))) )
(cdr l))))))))
'(1 2 3)) ; => 3
; ...........
; '(1 2 3 4)) ; => **error**
正如您正确猜测的,这是使用
(mk-length (lambda (x) (mk-length x))) ; (2) ; length≤∞
(mk长度(λ(x)(mk长度x));(2);长度≤∞代码>
在处理列表的下一个元素时
((lambda (x) (mk-length x)) (lambda (x) (mk-length x)))
=
(mk-length (lambda (x) (mk-length x)))
((λ(x)(mk长度x))(λ(x)(mk长度x)))
=
(mk长度(λ(x)(mk长度x)))
因此,无论列表的长度如何,它都适用于每个列表
通过eta转换,这只是(mk length mk length)
问题到底是什么?此外,您可能会在答案(或链接问题)中找到答案收件人:。我还不会将其标记为重复,因为我不确定您在这里要求的是什么。我的意思是,请执行与我粘贴到此处的第三个代码相同的操作。但应该来自第1个代码的想法。哪一个是
(((lambda (mk-length)
(mk-length mk-length))
(lambda (mk-length) ; (1)
(lambda (l)
(cond
((null? l ) 0)
(else (add1 ((mk-length ; (2) ; length≤2
(lambda (x) (mk-length eternity)) )
(cdr l))))))))
'(1 2))
((mk-length ; (2) ; length≤3
(lambda (x) (mk-length
(lambda (x) (mk-length eternity)))) )
(define (eternity x) (- 1)) ; to get an error instead of looping
(((lambda (mk-length)
(mk-length mk-length))
(lambda (mk-length)
(lambda (l)
(cond
((null? l ) 0)
(else (add1 ((mk-length ; (2) ; length≤3
(lambda (x) (mk-length
(lambda (x) (mk-length eternity)))) )
(cdr l))))))))
'(1 2 3)) ; => 3
; ...........
; '(1 2 3 4)) ; => **error**
(mk-length (lambda (x) (mk-length x))) ; (2) ; length≤∞
((lambda (x) (mk-length x)) (lambda (x) (mk-length x)))
=
(mk-length (lambda (x) (mk-length x)))