我必须以递归方式编写一个名为curry-skip的方案函数,它返回列表的第n个元素,以便
(((curry-skip 1) 'foo) 'bar) => bar
我似乎无法弄清楚如何递归地执行此操作。我还是相当新的Scheme,所以任何帮助都会非常感激! 感谢
答案 0 :(得分:3)
在看了你的例子后我写了以下内容。它似乎相当简单,因此我无法解释它是什么原因。
(define (curry-skip n)
(lambda (v) (if (= n 0)
v
(curry-skip (- n 1)))))
答案 1 :(得分:1)
我认为你有3个案例:
所以
(define (res val) ; [procedure used for case 2 - n=0]
(define (res0 . x) (if (null? x) val res0)) ; [case 3]
res0)
(define (curry-skip n)
(cond
((< n 0) (error "n is negative"))
((= n 0) res) ; [case 2 - n = 0]
(else (lambda x (curry-skip (- n 1)))))) ; [case 1 - n > 0]
然后
-> (((curry-skip 0) 'foo))
'foo
-> ((((curry-skip 0) 'foo) 'bar))
'foo
-> ((((curry-skip 1) 'foo) 'bar))
'bar
-> (((((curry-skip 0) 'foo) 'bar) 'baz))
'foo
-> (((((curry-skip 1) 'foo) 'bar) 'baz))
'bar
-> (((((curry-skip 2) 'foo) 'bar) 'baz))
'baz
与你的问题相比,我的解决方案还有一对额外的括号,但是我的结果尽可能接近。
答案 2 :(得分:-2)
(define (curry-skip n)
(if (zero? n)
(lambda (x) x)
(let ((rest (curry-skip (- n 1))))
(lambda (x) rest))))
您想要计算返回的(- n 1)
的{{1}}个案例 以外的案例!所以,在上面,当lambda
为零时,只返回一个参数lambda;但是,当n
为正数时,计算n
个案并返回一个忽略其参数的lambda,然后返回(- n 1)
。
请注意,虽然不是您的问题的一部分但与评论有关,但如果您需要真正的咖喱,例如在ML中,您需要语法帮助:
rest
注意递归如何为每个(define-syntax curry*
(syntax-rules ()
((_ (a) body ...) (lambda (a) body ...))
((_ (a b ...) body ...)
(lambda (a) (curry* (b ...) body ...)))))
创建词法环境,以便可以正确评估a, b, …
。 body
没有这种需要。
这里有一些代码解决了关于在返回的lambda中执行'curry-skip'的注释。在curry-skip
之外进行递归仅在创建一个闭包时发生;在lambda
内部执行此操作会在每次调用时创建闭包。
lambda