像 Typed Racket 的 'Rec' 类型这样的递归契约
recursive contract like Typed Racket's 'Rec' type
Typed Racket 的 Rec
类型是创建递归类型的简单方法:
#lang typed/racket/base
(define (deep (n : Integer)) : (Rec T (U Integer (List T)))
(if (zero? n)
n
(list (deep (- n 1)))))
有没有类似的递归契约的方法?
Racket的recursive-contract
不一样
合同表述只是表述!您可以编写一个宏来接收输入,例如 Typed Racket 的 Rec
并将 "recursive identifier" 替换为自引用。
这是一个示例 rec/c
组合器,其中 (rec/c id ctc)
扩展为 ctc
,所有出现的 id
都替换为 (recursive-contract id)
。
#lang racket/base
(require racket/contract (for-syntax racket/base syntax/parse))
(define-syntax-rule (rec/c t ctc)
(letrec ([rec-ctc
(let-syntax ([t (syntax-parser (_:id #'(recursive-contract rec-ctc)))])
ctc)])
rec-ctc))
(define/contract (deep n)
(-> integer? (rec/c t (or/c integer? (list/c t))))
(if (zero? n)
n
(list (deep (- n 1)))))
(deep 4)
注意:模式 _:id
匹配任何使用 t
作为标识符。
Typed Racket 的 Rec
类型是创建递归类型的简单方法:
#lang typed/racket/base
(define (deep (n : Integer)) : (Rec T (U Integer (List T)))
(if (zero? n)
n
(list (deep (- n 1)))))
有没有类似的递归契约的方法?
Racket的recursive-contract
不一样
合同表述只是表述!您可以编写一个宏来接收输入,例如 Typed Racket 的 Rec
并将 "recursive identifier" 替换为自引用。
这是一个示例 rec/c
组合器,其中 (rec/c id ctc)
扩展为 ctc
,所有出现的 id
都替换为 (recursive-contract id)
。
#lang racket/base
(require racket/contract (for-syntax racket/base syntax/parse))
(define-syntax-rule (rec/c t ctc)
(letrec ([rec-ctc
(let-syntax ([t (syntax-parser (_:id #'(recursive-contract rec-ctc)))])
ctc)])
rec-ctc))
(define/contract (deep n)
(-> integer? (rec/c t (or/c integer? (list/c t))))
(if (zero? n)
n
(list (deep (- n 1)))))
(deep 4)
注意:模式 _:id
匹配任何使用 t
作为标识符。