[racket] Typed Racket: limited polymorphism?

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Tue Jun 14 17:14:23 EDT 2011

I would have expected that something like this might approximate what you want: 

#lang typed/racket

(define-type SN (U String Number))

(define-predicate sn? SN)

(struct: (α) node ({left : α} {right : α}))

(: create-node (All (β) (β β -> (node SN))))
(define (create-node x y)
  (begin0
    (node x y)
    (unless (and (sn? x) (sn? y)) (error 'bad ""))))


ALAS, this raises a TR-internal error: 

> Welcome to DrRacket, version 5.1.1.5--2011-06-13(ed590b8/g) [3m].
> Language: typed/racket.
> match: no matching clause for Any




On Jun 14, 2011, at 12:35 PM, Richard Lawrence wrote:

> 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,
> Richard
> 
> _________________________________________________
>  For list-related administrative tasks:
>  http://lists.racket-lang.org/listinfo/users




Posted on the users mailing list.