像 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 作为标识符。