2009-11-11 44 views
3

在小策士的第9章中,作者提出了以下两种功能将Little Schemer的Q和P函数转换为Common Lisp?

(define Q 
    (lambda (str n) 
    (cond 
     ((zero? (remainder (first$ str) n)) 
     (Q (second$ str) n)) 
     (t (build (first$ str) 
     (lambda () 
      (Q (second$ str) n))))))) 

(define P 
    (lambda (str) 
    (build (first$ str)(lambda() (P (Q str (first$ str))))))) 

,并建议他们与以下执行评估:

(frontier (P (second$ (second$ int))) 10) 

你会怎么写P和Q Common Lisp中的函数?

(我有翻译在Y Combinator的自己 - 但我发现这一个挑战)

--Helper Functions--

(define frontier 
    (lambda (str n) 
    (cond 
     ((zero? n) (quote())) 
     (t (cons (first$ str) (frontier (second$ str) (sub1 n))))))) 

(define str-maker 
    (lambda (next n) 
    (build n (lambda() (str-maker next (next n)))))) 

(define int (str-maker add1 0)) 

(define second$ 
    (lambda (str) 
    ((second str)))) 

(define first$ first) 

(define build 
    (lambda (a1 a2) 
    (cond 
     (t (cons a1 
     (cons a2 (quote()))))))))) 

(define first 
    (lambda (p) 
    (cond 
     (t (car p))))) 

(define second 
    (lambda (p) 
    (cond 
     (t (car (cdr p)))))) 

(define add1 
    (lambda (n) 
    (+ 1 n))) 

(define remainder 
    (lambda (n m) 
    (cond 
     (t (- n (* m (/ n m)))))) 

(免责声明 - 这是不是一门功课的问题 - 这是我的理解和学习)

+0

为什么'Q'和'frontier'定义完全一样? “second $”和“first $”的定义是什么(它们与“second”和“first”相同)? – Svante 2009-11-11 17:13:55

+0

谢谢 - 更正 – hawkeye 2009-11-11 21:39:40

回答

6

我认为:

  • P中的定义,用“(Q(STR(第一个$ str)))“你的意思是:”(Q str(first $ str))“,因为Q是一个双参数函数。
  • 构建是做一个帮手创造一件对第一$和第二$工作:列表

考虑到这一点,直接翻译计划到Common Lisp的给出了:

(defun first$ (list) (first list)) 
(defun second$ (list) (funcall (second list))) 
(defun build (a b) (list a b)) 

(defun frontier (str n) 
    (if (zerop N) 
    () 
    (cons (first$ str) (frontier (second$ str) (1- n))))) 

(defun str-maker (next n) 
    (list n (lambda() (str-maker next (funcall next n))))) 

(setq int-maker (str-maker #'1+ 0)) 

(defun Q (str n) 
    (if (zerop (rem (first$ str) n)) 
    (Q (second$ str) n) 
    (list (first$ str) (lambda() (Q (second$ str) n))))) 

(defun P (str) 
    (list (first$ str) (lambda() (P (Q str (first$ str)))))) 

(frontier (P (second$ (second$ int-maker))) 10) 

谁最后一行返回:

(2 3 5 7 11 13 17 19 23 29) 

这是一个众所周知的系列,所以我假设翻译是成功的:-)