[racket] Typed Racket: limited polymorphism?
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