咖喱 - 跳过计划

时间:2014-01-28 03:05:13

标签: list scheme

我必须以递归方式编写一个名为curry-skip的方案函数,它返回列表的第n个元素,以便

(((curry-skip 1) 'foo) 'bar) => bar

我似乎无法弄清楚如何递归地执行此操作。我还是相当新的Scheme,所以任何帮助都会非常感激! 感谢

3 个答案:

答案 0 :(得分:3)

在看了你的例子后我写了以下内容。它似乎相当简单,因此我无法解释它是什么原因。

(define (curry-skip n) 
    (lambda (v) (if (= n 0) 
                    v 
                    (curry-skip (- n 1)))))

答案 1 :(得分:1)

我认为你有3个案例:

  1. n> 0 - 你向下递归直到n = 0
  2. n = 0 - 你记住参数,因为这是你需要返回的最终值;记忆是通过闭幕来完成的。
  3. else - 忽略参数直到完成,然后最后返回记忆值
  4. 所以

    (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