2013-03-29 88 views
1

如何測試流的cdr是否等於承諾?我試着寫一些東西,看起來像這樣:測試等於承諾

(equal? (stream-cdr s) #<promise>) 

它告訴我,語法#不正確,那麼什麼是寫這個正確的方法是什麼?

+0

你在使用什麼流庫?球拍的流實施? (由於'stream-cdr'過程,看起來不像這樣)srfi/40? SRFI/41? SICP式奇數流?特別指定? (然後將其作爲問題的一部分發布) –

+2

'#<...>'是Racket如何打印無法讀取的值;你不能在你的程序中使用該語法。你必須使用'delay'創建一個承諾;見Óscar的答案。 –

回答

2

這不起作用,「承諾」沒有價值 - 但。找到它的價值的唯一方法是通過迫使它或以其他方式評估它。根據它的實現方式,它可能是一個沒有參數的函數,等待被調用或者是一個延遲的對象,等待被強制。這有點像海森堡不確定性原理的情況 - 你不知道任何承諾的價值,直到你評估它的

當然,如果你評估承諾,比較是直接的。因爲它不是從什麼的問題流庫正在使用中不清楚,我會認爲使用delay一個特設的奇流執行(或者:lazy)和force(如SICP定義),就像這樣:

(define-syntax stream-cons 
    (syntax-rules() 
    ((stream-cons head tail) 
    (cons head (delay tail))))) ; also works using `lazy` in place of `delay` 

(define (stream-car stream) 
    (car stream)) 

(define (stream-cdr stream) 
    (force (cdr stream))) 

正如我所說,該比較將是直接的如果承諾首先計算:

(define promise (delay 42)) ; also works using `lazy` in place of `delay` 
(define stream (stream-cons 16 42)) 

promise 
=> #<promise:promise> 
(equal? (stream-cdr stream) promise) 
=> #f 
(equal? (stream-cdr stream) (force promise)) 
=> #t 
1

promisedelay的返回值(以及,在一些方案方言,make-promise)。你可以測試這個值與任何你喜歡的東西相等。例如:

> (define my-promise (delay "I'll always be good")) 
> (equal? "I'll always be good" my-promise) 
#f  # a string is not a promise 

在您的特定情況下#<promise>爲承諾一個計劃值的不可讀打印表示。打印表示不是一個值,因此您的Scheme實現會抱怨(「無法讀取」)。相反,如果你已經綁定#<promise>的東西,像some-promise,你可以嘗試:

(equal? (stream-cdr s) some-promise) 

注意,一個承諾不是它的價值;一個承諾,當被迫,返回一個值。那就是:

(equal? some-promise (force some-promise)) 

很少(從不?)是真的。

+1

R6RS沒有'make-promise',而R7RS'make-promise'沒有做你認爲它的做法(它對應於SRFI 45的'eager')。 R6RS在其核心庫中似乎沒有承諾,而R7RS的承諾是使用'delay','delay-force'('lazy')和'make-promise'('eager')創建的。 –