Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependent contracts for structs in Racket

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?

like image 584
sazf Avatar asked Nov 21 '25 15:11

sazf


1 Answers

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.

like image 119
Sorawee Porncharoenwase Avatar answered Nov 24 '25 15:11

Sorawee Porncharoenwase



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!