Это работает
#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, но :
импортируется #lang typed/racket
в фазе 0, поэтому вы получаете сообщение об ошибке:
:: 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
по-прежнему не проверяется статически.
Следите за вопросом здесь: stackoverflow.com/q/65447945/3414663
Следить за вопросом