在Little Schemer的第9章中,作者提出了以下两个函数
(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)
您如何在Common Lisp中编写P和Q函数?
(我自己翻译了Y-Combinator - 但我发现这个有挑战性)
- 助手功能 -
(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 :(得分:6)
考虑到这一点,将Scheme直接翻译成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)
这是一个众所周知的系列,所以我认为翻译是成功的: - )