Simeon
Simeon

Reputation: 143

Conditioning on defined types in Racket

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

Answers (2)

Gibstick
Gibstick

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

Brendan Cannell
Brendan Cannell

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

Related Questions