How to create a recursive contract - racket/racket GitHub Wiki
You can use flat-rec-contract
to build a recursive flat contract.
As an example, let's say a value is considered a tree if it's either
- a symbol, representing content of a leaf node
- a list, representing an internal node, where
- the first element of the list must be a symbol, representing content of the internal node, and
- other elements must be trees, representing subtrees of the internal node.
A flat contract testing if a value is a tree tree/c
can be defined as follows:
(define tree/c (flat-rec-contract t
(or/c symbol?
(cons/c symbol? (listof t)))))
Following shows usage of the contract that we defined.
EXAMPLES: WELL-FORMED TREES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
S1
(tree/c 'S1) ;-> #t
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
S1
|
S2
(tree/c '(S1 S2)) ;-> #t
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
S1
____|____
| | |
S2 S3 S4
__|__
| |
S3-1 S3-2
__|___
| |
S3-1-1 S3-1-2
(tree/c '(S1 S2 (S3 (S3-1 S3-1-1 S3-1-2) S3-2) S4)) ;->#t
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
COUNTEREXAMPLES: MALFORMED TREES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(tree/c '((a b))) ;#->f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(tree/c '((a b) (c d))) ;#->f
|#