我正在尝试在Scheme中编写Clojure的partition-all
函数的实现:
(define (take lst n)
(if (= n 0)
'()
(cons (car lst) (take (cdr lst) (- n 1)))))
(define (partition-all n step coll)
(if (not (null? coll))
(cons (take coll (min n (length coll)))
(partition-all n step (list-tail coll step)))))
但是口译员对我大吼:
cdr: expected pair in argument #1
这意味着,在某些时候,一个空列表'()
正在传递给take
,由于(not (null? coll))
函数中的条件partition-all
,该列表永远不会发生。
我的功能出了什么问题?
答案 0 :(得分:1)
根据我在评论中所说的内容,我非常确定{strong> cdr
take
给你提出问题。在ideone上以诡计运行你的代码给了我:
错误:在程序列表尾部:
错误:在过程list-tail中:位置1中的错误类型参数(期望对):()
因此,问题在于你试图获得一个不够长的列表尾部。只需采用最小step
和集合长度:
(define (take lst n)
(if (= n 0)
'()
(cons (car lst) (take (cdr lst) (- n 1)))))
(define (partition-all n step coll)
(if (not (null? coll))
(cons (take coll (min n (length coll)))
(partition-all n step (list-tail coll (min (length coll) step))))
;;^^^^^^^^^^^^^^^^^
'()
;;^^^
))
(display (partition-all 3 2 '(a b c d e f g)))
; => ((a b c) (c d e) (e f g) (g))
请注意,我还向if
添加了一个else案例,否则结果列表不会以'()
(空列表)结束,但会带有未指定的值。
另请注意,您的两个函数都不是尾递归的。