# [racket] Polymorphic types and curried functions

 From: Jack Firth (jackhfirth at gmail.com) Date: Wed Nov 12 20:56:44 EST 2014 Previous message: [racket] Index pairs question Next message: [racket] Polymorphic types and curried functions Messages sorted by: [date] [thread] [subject] [author]

```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