如何做一个懒列表中热切的语言?
-
13-09-2019 - |
题
我想使方案懒列表。这是我到目前为止所。
;; Constructor for Pairs
(define (cons-stream a b)
(cons a (λ() b)))
;; Selectors
(define (car-stream a-stream)
(car a-stream))
(define (cdr-stream a-stream)
((cdr a-stream)))
;; Lazy List using the pairs
(define (lazy-list from)
(cons-stream from (lazy-list (+ from 1))))
;; Take function
(define (take a-lazy-list number)
(define (take-helper i )
(if(= i number)
empty
(cons (car a-lazy-list) (take-helper (+ i 1)))))
(take-helper 0))
与所述懒惰列表中的问题是,流程评估内表达(懒惰列表(+ 1))第一造成进入无限递归的过程。
有一种方法使CON-流借此内表达而没有任何评价
解决方案
在解决方案是使用一个宏。我不是专家的方案(尤其是未对宏),但也许这个片段可以作为启示:
(define-syntax pointer-to
(syntax-rules ()
((pointer-to var)
(make-pointer
(lambda () var) ; the "pointer dereference" operation
(lambda (value) (set! var value)))))) ; "pointer write"
它用于如下:
(define x 1)
(define px (pointer-to x))
(pointer-set! px 2) ; this (in some sense) becomes `(set! x 2)'
因此,也许你想要的东西,像
(define-syntax lazy-cons
(syntax-rules ()
((lazy-cons head lazytail)
(cons head (lambda () lazytail)))))
但我不知道。看看define-syntax
。
其他提示
如果你不想去的宏观路线,你总是可以只放弃cons-stream
和重写lazy-list
如下:
(define (lazy-list from)
(cons from (λ() (lazy-list (+ from 1)))))
这可能是最简单,最实用的解决方案,但它只是制作递增的数字的懒列表好。
:你可以通过传递函数调用时,将产生该列表的连续元素概括这(define (lazy-list-gen generator)
(cons (generator)
(λ() (lazy-list-gen generator))))
(define (lazy-list from)
(lazy-list-gen
(λ()
(let ((ret from))
(set! from (+ from 1))
ret))))
此工作得很好:
> (define x (lazy-list 1))
> (car-stream x)
1
> (car-stream (cdr-stream x))
2
但是,有一个错误中的代码:
... continuing from above ...
> (car-stream (cdr-stream x))
3
此错误是因为调用cdr-stream
电话再次generator
。我们可以通过缓存拉姆达的返回值解决这个问题:
(define (lazy-list-gen generator)
(cons (generator)
(let ((gen-cache #f))
(λ()
(cond ((not gen-cache)
(set! gen-cache (lazy-list-gen generator))))
gen-cache))))
现在它的工作原理,它应:
> (define x (lazy-list 1))
> (car-stream x)
1
> (car-stream (cdr-stream x))
2
> (car-stream (cdr-stream x))
2
> (car-stream (cdr-stream (cdr-stream x)))
3
> (car-stream (cdr-stream x))
2
方案A懒惰列表被称为流。 这里的标准介绍。一>
不隶属于 StackOverflow