如何在打字球拍中定义语法?

问题描述 投票:0回答:1

这有效

#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
吗?

racket typed-racket
1个回答
2
投票
#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
中的代码仍然没有进行静态类型检查。

© www.soinside.com 2019 - 2024. All rights reserved.