On 01/22/2015 11:39 AM, Luke Whittlesey wrote:
For background, this code works::
---- begin working code ----
#lang typed/racket
(define-type Wire Symbol)
(define Wire? (make-predicate Wire))
(define-type WireVec (Listof Wire))
(define WireVec? (make-predicate WireVec))
;; dispatch based on type
(: Not (case-> (Wire -> Wire)
(WireVec -> WireVec)))
(define (Not wire*)
(if (Wire? wire*)
(Not-wire wire*)
(Not-wirevec wire*)))
(: Not-wire (Wire -> Wire))
(define (Not-wire w)
(displayln "received wire")
w)
(: Not-wirevec (WireVec -> WireVec))
(define (Not-wirevec w)
(displayln "received wirevec")
w)
;; test
(Not 'my-wire)
(Not (list 'a 'b 'c))
;;; printed results are
;received wire
;'my-wire
;received wirevec
;'(a b c)
---- end working code ----
;; define types with promises as well
(define-type Wire (U (Promise Wire) Symbol))
(define Wire? (make-predicate Wire)) ; <-- error
(define-type WireVec (U (Promise WireVec) (Listof Wire)))
(define WireVec? (make-predicate WireVec)) ; <-- error
I don't usually make predicates when writing TR code, mostly for this
reason. Fortunately, it's often possible to use the predicates for
first-order data types to narrow down types enough. It's possible in
your case, for example:
#lang typed/racket
(define-type Wire (U (Promise Wire) Symbol))
(define-type WireVec (U (Promise WireVec) (Listof Wire)))
;; dispatch based on type
(: Not (case-> (Wire -> Wire)
(WireVec -> WireVec)))
(define (Not wire*)
(cond [(symbol? wire*) (Not-wire wire*)]
[(list? wire*) (Not-wirevec wire*)]
[else (delay (Not (force wire*)))]))
(: Not-wire (Wire -> Wire))
(define (Not-wire w)
(displayln "received wire")
w)
(: Not-wirevec (WireVec -> WireVec))
(define (Not-wirevec w)
(displayln "received wirevec")
w)
;; test
(Not 'my-wire)
(Not (list 'a 'b 'c))
That's only a guess at what `Not` is supposed to do, though. If you need
to make a decision without first forcing the promise, you'll need to use
different types.
Neil ⊥
____________________
Racket Users list:
http://lists.racket-lang.org/users