[racket] Polymorphic types and curried functions
I've been mucking around with Typed Racket some and was writing a
polymorphic curried function when something I found counter-intuitive
popped up. I had this function:
(: compare-projection (All (A B) (-> (-> A A Boolean) (-> (-> B A) (->
B B Boolean)))))
(define (((compare-projection a<) b->a) b1 b2)
(a< (b->a b1) (b->a b2)))
The purpose of this function was to let me compare things by converting
them to some other type with a known comparison function, so something like
symbol<? (which is defined in terms of bytes<? according to the docs) could
be implemented directly like this:
(define symbol<? ((compare-projection bytes<?) (compose
string->bytes/utf-8 symbol->string)))
The problem I was having was that the first initial argument, bytes<?, only
specifies the first type variable A. The other type variable B can still be
anything, as it depends on what function you use to map things to type A in
the returned function. The All type therefore assumes Any type for B,
making the returned type non-polymorphic.
I expected something like currying to occur in the polymorphic type, since
the returned type is a function. I thought that if a polymorphic function
1) returns a function and 2) doesn't have enough information from it's
arguments to determine all it's type variables, that it should then
automatically return a polymorphic function. In other words, I thought this
type would be equivalent to this automatically:
(All (A) (-> (-> A A Boolean) (All (B) (-> (-> B A) (-> B B Boolean)))))
This is most certainly not the case, though I wonder - would it be terribly
difficult to define some sort of polymorphic type constructor that *did*
behave like this? I'm fiddling with some macros for syntactic sugar of type
definitions and it would be a boon to not have to worry about this.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20141112/38d0a80f/attachment.html>