Reputation: 143
I have defined the following types in Racket:
(define-type vname (Pairof String Integer))
(define-type term (U vname (Listof (Pairof String term))))
(define-type subst (Listof (Pairof vname term)))
How would I define a procedure (lift s t)
with signature (-> subst term term)
that is conditioned on whether t
is of type vname
or (Listof (Pairof String term))
? Is there a an easy way to test the actual type of a union type? If I instead had (define-type term (U String Integer))
, I could use string?
to test whether t
is a string; how would I extend this to my situation?
Upvotes: 0
Views: 171
Reputation: 737
I've run into similar issues in Typed Racket and I found it simpler to define structs for all of my nontrivial types. Then you can distinguish between types using the struct predicates, eg.
(struct vname (name val))
(vname? (struct "foo" 5))
Upvotes: 1
Reputation: 679
A union is not a discriminated union, so there isn't automatically a way to do this. However, in this particular case you can distinguish between the two because a vname
will always be a pair with an Integer
in the cdr
position, whereas a value of type (Listof (Pairof String term))
will be either '()
or else will be a pair with a (possibly empty) list in the cdr
position. So the predicate vname?
could be defined as:
(define (vname? x)
(and (pair? x) (exact-integer? (cdr x))))
Upvotes: 0