[racket] Typed Racket: problem with interaction between typed/untyped modules

From: Ismael Figueroa Palet (ifigueroap at gmail.com)
Date: Fri Dec 2 17:38:26 EST 2011

Greetings,

I'm trying to implement a function wrapper, that given any function returns
a function of the same type, but that maybe applies a different argument.
So far I haven't been successful, and based on previous questions to the
mail list it seemed that I needed to go to an untyped module because I
couldn't constraint values to a given type.

With this approach I encountered a problem, that originates in the
contracts for polymorphic functions, I made a minimal example of my problem
below:

Module1
#lang racket
; (All (A B) ((A -> (T B)) A -> (T B)))
(define (untyped-wrap fun value)
  (fun "blabla"))

(provide untyped-wrap)

Module2
#lang typed/racket
(struct: (A) T ([value : A]))

(require/typed "untyped-wrap.rkt"
               [untyped-wrap (All (A B) ((A -> (T B)) A -> (T B)))])

(: wrap (All (A B) ((A -> (T B)) A -> (T B))))
(define (wrap fun value)
  (untyped-wrap fun value))

(: f (Any -> (T One)))
(define (f x) (T 1))

When I, from the typed Module1, evaluate:

(wrap f 1)

I get the error:

untyped-wrap: self-contract violation, expected a(n) A16; got: "blabla"
  contract from: (interface for untyped-wrap), blaming: (interface for
untyped-wrap)
  contract:
    (recursive-contract
     (parametric->/c
      (A16 B17) .......

My guesses:

First I thought that this should work because at the time I apply
untyped-wrap it is known that A = Any and B = One. But then I realized that
the typesystem can't prove that "blabla" is the right type for all A.

 Then I thought about instantiating the polymorphic function this way:

(: wrap (All (A B) ((A -> (T B)) A -> (T B))))
(define (wrap fun value)
  ( (inst untyped-wrap A B) fun value))

guessing again that A = Any and B = One should be known

but it fails with the same error....

When I write the concrete types it works.

I've been trying to write code to deal with functions in a general way,
while preserving the type, but it seems very hard to do right now in
typed/racket :-(

For instance, I had to make an ad-hoc cast going to an untyped module to
implement a function with type
(All (C D) (EL (C -> (EL D))) -> (EL (C -> (EL D)))), and then I tried the
same approach here, but this new error came up

I think it should be useful to provide a 'cast' operation. I think then I
could say something like, relying on contracts for checking at runtime:

Module2
#lang typed/racket
(struct: (A) T ([value : A]))

(require/typed "untyped-wrap.rkt"
               [untyped-wrap (Procedure Any -> (T Any))])
(: wrap (All (A B) ((A -> (T B)) A -> (T B))))
(define (wrap fun value)
  [CAST (untyped-wrap fun value) (T B)])

(: f (Any -> (T One)))
(define (f x) (T 1))

any suggestions on how can I achieve the behavior I want??

Thanks

-- 
Ismael
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20111202/53cccb6b/attachment.html>

Posted on the users mailing list.