Racket流会记住他们的元素吗?

far*_*d99 4 stream racket

在从无限流中计算大量数字时,Racket会使用memoization吗?因此,例如,如果我打印出(也就是计算和显示)无限整数流上的前400个数字:(1 2 3 ... 399 400)我刚要求打印前500个数字无限的流.第二组计算会使用memoization吗?那么前400个数字不会再次计算?

或者,此功能是否需要由用户编码/从库中获取?

Jac*_*ack 10

内置的球拍/流库使用延迟评估和记忆来从流中绘制元素:

(require racket/stream)

(define (print-and-return x)
  (displayln "drawing element...")
  x)

(define (in-range-stream n m)
  (if (= n m)
      empty-stream
      (stream-cons (print-and-return n) (in-range-stream (add1 n) m))))

(define s (in-range-stream 5 10))

(stream-first s)
(stream-first s)
(stream-first (stream-rest s))
Run Code Online (Sandbox Code Playgroud)

在stream-cons使用stream-first或请求之前,不会评估传递给的表达式stream-rest.一旦评估,它们就会被记忆.请注意,尽管执行了四个流操作s,但只显示两个"绘图元素..."消息.


Gre*_*ott 5

你可以使用这个memoize包.

GitHub来源:https://github.com/jbclements/memoize/tree/master

raco pkg install memoize

使用它是在更换简单define用define/memo.引用它的例子:

(define (fib n)                                     
  (if (<= n 1) 1 (+ (fib (- n 1)) (fib (- n 2)))))  

> (time (fib 35))                                   
cpu time: 513 real time: 522 gc time: 0             
14930352                                            

> (define/memo (fib n)                              
    (if (<= n 1) 1 (+ (fib (- n 1)) (fib (- n 2)))))

> (time (fib 35))                                   
cpu time: 0 real time: 0 gc time: 0                 
14930352      
Run Code Online (Sandbox Code Playgroud)

此外,使用Racket哈希表自己实现memoization通常很容易.