生成素数时的“应用:不是程序”

时间:2013-02-10 18:29:37

标签: scheme

我正在尝试输出前100个素数并不断收到错误:

申请:不是程序; 期望一个可以应用于参数的过程   给出:(#)   参数......:[无]

错误显示在我的take $ procedure中:

(if (or (= m 0) (null? st))
      '()
      (cons (car st) (take$ (- m 1) ((cdr st)))))))

这是我的所有代码:

(define int-builder$
    (lambda (x)
       (list x (lambda () (int-builder$ (+ 1 x ))))))

(define take$
    (lambda (m st)
       (if (or (= m 0) (null? st))
           '()
           (cons (car st) (take$ (- m 1) ((cdr st)))))))

(define filter-out-mults$
   (lambda (num  st)
     (cond
     (( = (remainder (car st) num) 0) 
         (filter-out-mults$ num ((cadr st))))
         (else 
            (list (car st) (lambda () (filter-out-mults$ num ((cadr st)))))))))

(define sieve$
   (lambda (st)
     (list (car st)
          (lambda() (sieve$ (filter-out-mults$ (car st) ((cadr st))))))))

(define stol$
    (lambda (n) 
      (take$ n (sieve$ (int-builder$ 2)))))

感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:4)

您的问题是您在使用抽象筛网时的表现并不一致。

是这样定义的筛子:

;; A Sieve is a (cons n p), where
;;    n is a Natural Number
;;    p is a Procedure that takes no arguments and returns a Sieve

或是否像这样定义

;; A Sieve is a (list n p), where
;;    n is a Natural Number
;;    p is a Procedure that takes no arguments and returns a Sieve

在代码中的某些地方,您正在提取p并按如下方式调用它: ((cdr st));在其他地方,像这样:((cadr st))

你问题的评论者之所以对每一个问题都持批评态度的原因是你没有给出关于形成Sieves和从Sieves中提取子部分的规则的高级定义。像上面这样的数据定义会有所帮助。

对我来说,在我添加数据定义,合同,然后开始单独测试您的功能之后,我很快发现了问题。 (提示:它与上述((cdr st))((cadr st))之间的不一致有关。)

这是我的代码版本。它通过将Sieve表示隐藏在抽象接口后面来本地化Sieve表示的选择;我使用宏来执行此操作,因为流构造函数想要延迟对其接收的表达式的求值(尽管可以通过更改接口来解决此问题,因此Sieve构造函数需要采用筛选生成过程而不是直接表达式)

练习阅读器:使用当前的api,如果有人遵循我在此代码中给出的数据定义,stream-empty?永远不会返回true;你怎么能证明这一点?

;; A Stream is a (list Nat (-> () Stream))
;; but this knowledge should not be used anywhere but in the
;; procedures (and special form) stream-rest, stream-first, stream,
;; and stream-empty?.

;; stream-rest: Stream -> Stream
(define (stream-rest st) ((cadr st)))

;; stream-first: Stream -> Nat
(define (stream-first st) (car st))

;; Special Form: (stream <natural-number> <stream-expr>) is a Stream
(define-syntax stream
  (syntax-rules ()
    ((stream n expr) (list n (lambda () expr)))))

;; Stream -> Boolean
(define (stream-empty? st) (null? st))


;; Nat -> Stream
(define (int-builder$ x)
  (stream x (int-builder$ (+ 1 x))))

;; Nat Stream -> [Listof Nat]
(define (take$ m st)
  (if (or (= m 0) (stream-empty? st))
      '()
      (cons (stream-first st) (take$ (- m 1) (stream-rest st)))))

;; Nat Stream -> Stream
(define (filter-out-mults$ num st)
  (cond
   (( = (remainder (stream-first st) num) 0)
    (filter-out-mults$ num (stream-rest st)))
   (else 
    (stream (stream-first st) (filter-out-mults$ num (stream-rest st))))))

;; Stream -> Stream
(define (sieve$ st)
  (stream (stream-first st)
          (sieve$ (filter-out-mults$ (stream-first st) (stream-rest st)))))

;; Nat -> [Listof Nat]
(define (stol$ n)
  (take$ n (sieve$ (int-builder$ 2))))