Racket 中结构的依赖合同

Dependent contracts for structs in Racket

假设我用 "center".

为集合定义了一个结构
(struct centered-set (center elems))

我要保证以下条件

我可以用#:guard表达条件。有没有办法表达和合同一样的条件?

对于函数,->i 用作那种依赖契约的组合器。如何表达结构体的依赖契约?

IIUC,contract-out 不支持此类内容。但是,您可以通过手动提供带有合同的构造函数和访问器来模拟功能:

#lang racket

(module foo racket
  (provide (contract-out [bt (-> any/c any/c any/c (bst/c 1 10))]
                         [bt-val (-> (bst/c 1 10) any/c)]
                         [bt-left (-> (bst/c 1 10) any/c)]
                         [bt-right (-> (bst/c 1 10) any/c)]))

  (define (bst/c lo hi)
    (or/c #f
          (struct/dc bt
                     [val (between/c lo hi)]
                     [left (val) #:lazy (bst/c lo val)]
                     [right (val) #:lazy (bst/c val hi)])))

  (struct bt (val left right)))

(require 'foo)

(bt 11 #f #f)

应该可以写一个provide transformer来自动化这个过程。