Suppose I define a struct for a set with its "center".
(struct centered-set (center elems))
I want to guarantee the following conditions.
elems
is a set.center
is an member of elems
.I can express the conditions with #:guard
. Is there a way to express the same conditions as a contract?
For functions, ->i
works as a combinator for that kind of dependent contracts. How to express dependent contracts for structs?
IIUC, contract-out
doesn't support anything like that. However, you can simulate the functionality by providing the constructor and accessors manually with the contract attached:
#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)
It should be possible to write a provide transformer to automate this process.