我是计划新手,我写了一个小程序,根据开始和结束索引从列表中获取原子。
(define counter 0)
(define (sub x y a_list)
(cond
((null? a_list) '())
((and (>= counter x) (< counter y)) (cons x (sub x y (cdr a_list))))
(else((set! counter (+ counter 1)) (sub x y (cdr a_list))))
))
我没有看到这个代码有任何问题,但是当我执行它时,例如:
(sub 1 3 '(X G H S E))
我收到以下错误:
function call: expected a function after the open parenthesis, but received (void)
答案 0 :(得分:3)
我建议如下:
(define (sub x y lst)
(let loop ((lst lst) (counter 0))
(cond
((null? lst)
'())
((and (>= counter x) (< counter y))
(cons (car lst) (loop (cdr lst) (+ 1 counter))))
(else
(loop (cdr lst) (+ 1 counter))))))
你的代码,重写,将是
(define counter 0)
(define (sub x y a_list)
(cond
((null? a_list)
'())
((and (>= counter x) (< counter y))
(begin
(set! counter (+ counter 1))
(cons (car a_list) (sub x y (cdr a_list)))))
(else
(begin
(set! counter (+ counter 1))
(sub x y (cdr a_list))))))
但第二次执行失败,因为计数器未重置为0:
(sub 1 3 '(X G H S E))
=> '(G H)
(sub 1 3 '(X G H S E))
=> '()
关于你的初步问题:
在只允许使用一种表单的地方对表单进行分组(if
可以考虑),使用begin
(有关详细信息,请参阅优秀的Racket帮助)
((f x ...) y ...)
首先评估(f x ...)
,它应该返回一个程序p
;然后它评估(p y ...)
。在您的情况下,f
为set!
,总是评估为(void)
,因此评估为((void) y ...)
。因此错误信息。
编辑
在没有计数器的情况下说明@ WorBlux的想法:
(define (sub x y lst)
(cond
((or (null? lst) (<= y 0))
'())
((> x 0)
(sub (- x 1) (- y 1) (cdr lst)))
(else
(cons (car lst) (sub (- x 1) (- y 1) (cdr lst))))))
答案 1 :(得分:1)
在这个问题上你实际上并不需要一个计数器只是想一下递归的模式
(sub xy L)等于(sub(?x)(?y)(cdr L))其中x大于零,相当于(?(?L)(sub x(?y) (cdr L)))其中x为0但y为正且相当于空列表,其中y小于零。