这有效
#lang racket
(begin-for-syntax
(define (foo n)
(+ n 3)))
所以我也希望这能起作用
#lang typed/racket
(: foo : Real -> Real)
(define-for-syntax (foo n)
(+ n 3))
但是如果失败了
; :: undefined;
; cannot reference an identifier before its definition
之后我依次尝试了以下各项
typed/racket
(define-for-syntax (foo (n : Real)) : Real
(+ n 3))
(begin-for-syntax
(: foo (-> Real Real))
(define (foo n)
(+ n 3)))
(begin-for-syntax
(define (foo (n : Real)) : Real
(+ n 3)))
每一次都因为这样或那样的原因而失败。难道
typed/racket
应付不了{begin|define}-for-syntax
吗?
#lang typed/racket
(: foo : Real -> Real)
(define-for-syntax (foo n)
(+ n 3))
失败:
Type Checker: Declaration for `foo' provided, but `foo' has no definition
对我来说,这完全有道理。
foo
是在第1阶段定义的,所以类型声明在第0阶段找不到它的定义。
(begin-for-syntax
(: foo (-> Real Real))
(define (foo n)
(+ n 3)))
比较“正确”,但仍然存在很多问题。代码处于第 1 阶段,但
:
在第 0 阶段由 #lang typed/racket
导入,因此出现错误:
:: undefined
但是,另一个主要问题是,即使您在第 1 阶段成功导入了
:
,类型检查器仍然无法正常工作。
简而言之,以下是让它发挥作用的方法。
#lang typed/racket
(module for-syntax-mod typed/racket
(provide foo)
(: foo (-> Real Real))
(define (foo n)
(+ n 3)))
(require (for-syntax 'for-syntax-mod))
(begin-for-syntax (println (foo 10)))
这在语言
foo
的子模块 for-syntax-mod
中声明了 typed/racket
,因此类型检查器现在将按预期在此子模块上工作。然后我们在第 1 阶段导入这个子模块,所以现在 foo
在 begin-for-syntax
中可用。请注意,begin-for-syntax
中的代码仍然没有进行静态类型检查。