如何使用 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")))
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")))