如何使用 with-type 在非类型化模块中使用 Typed Racket 片段?

How do I use with-type to use Typed Racket fragments within untyped modules?

Typed Racket reference indicates that it's possible to use with-type 在非类型化代码中创建“类型化区域”。

The with-type form allows for localized Typed Racket regions in otherwise untyped code.

虽然还不清楚如何实际使用。显然,使用这样的功能需要在使用 #lang racket 或类似的东西的无类型模块中进行。 with-type 绑定应该如何导入?

天真的尝试只是 require Typed Racket,但这会导致 TR 覆盖现有句法形式的失败。

(require typed/racket)

(struct point (x y)) ; complains about missing type annotations

尝试使用 only-in 来简单地要求 with-type 并且没有其他任何工作,但是 none 所需的类型绑定(例如 Number->) 存在。

似乎唯一的方法就是手动使用 only-in 只导入我需要的东西,但这感觉很费力。我也可以使用 prefix-in,但当然所有内容都会分散在前缀中。

是否有推荐的方法,或者此功能是否有些过时?

我不知道根本的答案。一个猜测是,它是那种在编写宏时有用的东西,而不是你直接编写的代码?

一个实用的想法:可以用local-require来限制TR require的"contamination"。如果工作量比 only-in.

少,您可以转而使用 except-in

例如,文档中的这个示例很接近,但给出了一个奇怪的错误,大概是因为它使用了 TR 的 quote:

#lang racket/base

(let ([x 'hello])
  (local-require typed/racket)
  (with-type
    #:result String
    #:freevars ([x String])
    (string-append x ", world")))
; /tmp/so.rkt:7:21: quote: identifier used out of context
;   in: quote

except-in 排除它会给出所需的错误:

(let ([x 'hello])
  (local-require (except-in typed/racket quote))
  (with-type
    #:result String
    #:freevars ([x String])
    (string-append x ", world")))
; x: broke its contract
;   promised: String
;   produced: 'hello
;   in: String
;   contract from: /tmp/so.rkt
;   blaming: /tmp/so.rkt
;    (assuming the contract is correct)
;   at: /tmp/so.rkt:14.17

但是是的。这只是在摆弄边缘,没有深入到它的核心。

我只会使用 except-in(或者 rename-in)来避免在类型化和非类型化程序中都不起作用的少数标​​识符。像这样修改 Greg 的程序:

#lang racket/base

(require (except-in typed/racket struct))

(struct point (x y))

(let ([x 'hello])
  (with-type
    #:result String
    #:freevars ([x String])
    (string-append x ", world")))