2017-04-11 93 views
1

我正在使用Little Schemer,我试图将所有答案转换为Common Lisp。 在第8章中,讨论了匿名函数,并返回了匿名函数。 例如:通过匿名函数循环常见Lisp vs. Scheme

(define insertL-f 
    (lambda (test?) 
     (lambda (new old l) 
      (cond 
       ((null? l) (quote())) 
       ((test? (car l) old) (cons new l))) 
       (else (cons (car l) ((insertL-f test?) new old (cdr l)))))))) 

我的代码:

(defun insertL-f (test) 
    (lambda (new old l) 
     (cond 
      ((null l) '()) 
      ((funcall test (car l) old) (cons new l)) 
      (t (cons (car l) (insertL-f test) new old (cdr l)))))) 

问题是代码的第二块的最后一行。我得到的错误是“cons的参数太多”,但我不能像Scheme代码那样添加一对额外的括号。这种风格的递归在Common Lisp中是不可能的吗?

回答

2
(defun insertL-f (test) 
    (lambda (new old l) 
    (cond 
    ((null l) '()) 
    ((funcall test (car l) old) (cons new l)) 
    (t (cons (car l) 
       (funcall (insertL-f test) 
         new 
         old 
         (cdr l))))))) 
2

insertL-f返回功能,在您的计划版本,应用它,而在CL具有扁平的列表,而不是如果与funcall应用它不过好像是要返回的功能等于它取了一个这样你就可以通过与本地labels定义它缓存它:使用

(defun insert-l-f (test) 
    (labels ((func (new old l) 
      (cond 
       ((null l) '()) 
       ((funcall test (car l) old) (cons new l)) 
       (t (cons (car l) (func new old (cdr l))))))) 
    #'func)) 

方案相同的本地define(这确实是一个letrec与平坦的语法):

(define (insert-l-f test?) 
    (define (func new old l) 
    (cond 
     ((null? l) (quote())) 
     ((test? (car l) old) (cons new l))) 
     (else (cons (car l) (func new old (cdr l))))) 
    func)