Как да тествам дали cdr на поток е равен на обещание? Опитвам се да напиша нещо, което изглежда така:
(equal? (stream-cdr s) #<promise>)
Казва ми, че синтаксисът # е неправилен, така че какъв е правилният начин да напиша това?
Как да тествам дали cdr на поток е равен на обещание? Опитвам се да напиша нещо, което изглежда така:
(equal? (stream-cdr s) #<promise>)
Казва ми, че синтаксисът # е неправилен, така че какъв е правилният начин да напиша това?
Това няма да работи, едно „обещание“ няма стойност - все още. Единственият начин да намерите стойността му е като го принудите или оцените по друг начин. В зависимост от начина, по който е имплементиран, може да е функция без аргументи, чакаща да бъде извикана, или забавен обект, чакащ да бъде принуден. Това е нещо като ситуация на принципа на неопределеността на Хайзенберг - не можете да знаете стойността на произволно обещание, докато не го оцените.
Разбира се, ако оцените обещанието, сравнението е лесно. Тъй като от въпроса не става ясно каква библиотека с потоци се използва, ще приема внедряване на ad-hoc странни потоци, използвайки 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
promise
е върнатата стойност на delay
(и, в някои диалекти на Scheme, 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>
е нечетливо печатно представяне на стойност на схема за обещание. Отпечатаното представяне не е стойност и по този начин внедряването на вашата схема ще се оплаква („не може да се чете“). Ако вместо това бяхте обвързали #<promise>
с нещо, като some-promise
, можеше да опитате:
(equal? (stream-cdr s) some-promise)
Имайте предвид, че обещанието не е неговата стойност; обещанието, когато е принудено, връща стойност. Това е:
(equal? some-promise (force some-promise))
рядко (никога?) е вярно.
make-promise
, а R7RS make-promise
не прави това, което мислите, че прави (съответства на eager
на SRFI 45). R6RS изглежда няма обещания в основната си библиотека, а обещанията на R7RS са създадени с помощта на delay
, delay-force
(lazy
) и make-promise
(eager
).
- person Chris Jester-Young; 30.03.2013
stream-cdr
) srfi/40? srfi/41? Странни потоци в стил SICP? ad-hoc? (след това го публикувайте като част от въпроса) - person Óscar López   schedule 29.03.2013#<...>
е как Racket отпечатва стойности, които са нечетими; не можете да използвате този синтаксис във вашата програма. Трябва да създадете обещание, като използватеdelay
; вижте отговора на Оскар. - person Ryan Culpepper   schedule 29.03.2013