39 lines
937 B
Racket
39 lines
937 B
Racket
#lang typed/racket/base
|
|
(require (for-syntax racket/base))
|
|
|
|
;; Working around what appears to be a bug in Typed Racket
|
|
;; by implementing my own promises.
|
|
|
|
(provide my-delay my-force MyPromise)
|
|
|
|
|
|
(define-struct: Sentinel ())
|
|
|
|
|
|
(define-struct: (a) MyPromise ([forced? : Boolean]
|
|
[thunk : (-> a)]
|
|
[val : (U Sentinel a)])
|
|
#:mutable)
|
|
|
|
|
|
(define-syntax (my-delay stx)
|
|
(syntax-case stx ()
|
|
[(_ expr ...)
|
|
(syntax/loc stx
|
|
(make-MyPromise #f
|
|
(lambda () expr ...)
|
|
(make-Sentinel)))]))
|
|
|
|
(: my-force (All (a) (MyPromise a) -> a))
|
|
(define (my-force a-promise)
|
|
(cond
|
|
[(MyPromise-forced? a-promise)
|
|
(define val (MyPromise-val a-promise))
|
|
(if (Sentinel? val)
|
|
(error 'force "Impossible")
|
|
val)]
|
|
[else
|
|
(define val ((MyPromise-thunk a-promise)))
|
|
(set-MyPromise-val! a-promise val)
|
|
(set-MyPromise-forced?! a-promise #t)
|
|
val])) |