首页 > 解决方案 > Applying cast to dynamically required function in typed racket

问题描述

I'm trying to load and use a function from a different module at run-time. The issue is that dynamic-require's range, Any, can't seem to be casted to a more specific (function) type.

test.rkt:

#lang typed/racket

(module other-module typed/racket
  (provide f)
  (: f : Integer -> Integer)
  (define (f x)
    (* x 2)))

; g has type Any because dynamic-require returns a value of type Any
(define g (dynamic-require '(submod "test.rkt" other-module) 'f))

;contract violation
;  Attempted to use a higher-order value passed as `Any` in untyped code: #<procedure:f>
;  in: Any
;  contract from: typed-world
;  blaming: cast
;   (assuming the contract is correct)
((cast g (-> Integer Integer)) 3)

Is there any way to load and use a function at run-time from a different module in #lang typed/racket?

标签: rackettyped-racket

解决方案


One work-around is to do the loading in an untyped module and use require/typed to assign types:

#lang typed/racket

(module other-module typed/racket
  (provide f)
  (: f : Integer -> Integer)
  (define (f x)
    (* x 2)))

(module another-module racket
  (define g (dynamic-require '(submod "test.rkt" other-module) 'f))
  (provide g))

(require/typed 'another-module
  (g (-> Integer Integer)))

(g 3)
;; 6

But yeah, it would be nicer if dynamic-require could take a target type or Typed Racket allowed untyped regions (the opposite of with-type).


推荐阅读