[racket] Typed Racket: limited polymorphism?

From: Richard Lawrence (richard.lawrence at berkeley.edu)
Date: Tue Jun 14 12:35:48 EDT 2011

Hi all,

I have another question about whether something is possible in Typed
Racket.  What I would like to do is define a polymorphic structure where
the polymorphism is limited to a certain subset of types.  Again, I'm
not sure I'm using the terminology correctly, so here's an example.

Right now, I can do this:

#lang typed/racket
; I can define a polymorphic structure with no restrictions on the type
; variable A
(struct: (A) poly-node  
         ([left : A]
          [right : A]))

; I like this because it enforces that the left and right slots have the same
; type
(poly-node 3 3)
; ...but I want to be able to limit A to only certain types, e.g., so
; that this would produce a type error:
(poly-node '(whatever) '(as-long-as-its-the-same-type))

; An alternate route allows me to limit the types of left and right, but
; not enforce that they have the same underlying type
(define-type Dummy (U Number String))
(struct: dummy-node ([left : Dummy]
                     [right : Dummy]))

; I want these to be allowed...
(dummy-node 3 4)
(dummy-node "s" "t")
; but not this:
(dummy-node 3 "anything of type Dummy")

Ideally, what I'd like to be able to do is something like this:

; inspired by my incredibly minimal Haskell knowledge:
; the => operator restricts the type variable A to types in the type class
; Number-or-String
(define-type-class Number-or-String (Number String))
(struct: (A => Number-or-String) limited-poly-node
         ([left : A]
          [right : A]))

(limited-poly-node 3 4) ; OK
(limited-poly-node "s" "t") ; OK
(limited-poly-node 3 "s") ; type error: left and right not of the same type
(limited-poly-node 'f 'g) ; type error: Symbol is not in Number-or-String

If something like this is already possible in TR, I haven't been able to
figure out how to do it -- pointers would be appreciated.  If not, I
guess I have a feature request...

Thanks as always,

Posted on the users mailing list.