在The little schemer一书中,我们发现此功能仅支持长度小于或等于1的列表:
(((lambda (mk-length) ; A.
(mk-length mk-length))
(lambda (mk-length)
(lambda (l)
(cond
((null? l ) 0)
(else (add1 ((mk-length eternity ) (cdr l))))))))
'(1))
我想一步一步学习,并想编写类似的函数,仅支持长度小于或等于2的列表。
请不要通过提供以下代码来回答这个问题:
(((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)
TL; DR: (内部形式)计算,对于长度的列表作品功能0,并且将使用来计算将被用于工作在尾部函数(即的结果参数列表的)。(mk-length A)
cond
length
(A A)
length
(cdr ...)
您的第一个代码段(;A.
)仅适用于长度为0和1的列表。为了使工作2还,替换
(mk-length eternity) ; length≤1
与
(mk-length ; (2) ; length≤2
(lambda (x) (mk-length eternity)))
作品。
(注意:(mk-length eternity)
本身进行计算length≤0
,但是整体功能变为length≤1
;这是所有其他length≤i
注释所指的内容。)
仔细看
(((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))
我们可以看到,at的结果用于处理,而to at将在处理时替换为该调用。(mk-length ...)
;(2)
(cdr l)
argument
mk-length
;(2)
mk-length
(cddr l)
如果使用(如您的第一个代码),则可以正常处理,但自然会失败。(mk-length eternity)
(cdr l)
((eternity eternity) (cddr l))
如果使用,则处理正常,然后用于处理也正常的(因此长度2被正确处理),然后自然失败(对于长度3及以上)。(mk-length (lambda (x) (mk-length eternity)))
(cdr l)
((lambda (x) (mk-length eternity)) (lambda (x) (mk-length eternity))) = (mk-length eternity)
(cddr l)
((eternity eternity) (cdddr l))
因此,要处理最多三个元素的列表,
((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)))
因此适用于每个列表,无论其长度如何。
通过eta转换,这就是(mk-length mk-length)
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句