@@ -169,6 +169,56 @@ If your model can be either `A` or `B`, use the `:alt` node using `h/alt`.
169169 [:string (h/fn string?)])
170170```
171171
172+ ### Cat / Repeat
173+
174+ ` :cat ` and ` :repeat ` nodes represent sequences of models.
175+
176+ ``` clojure
177+ ; ; Sequential collection (list or vector) which contains
178+ ; ; 1 to 3 booleans, followed by
179+ ; ; 0 or 1 time integers, followed by
180+ ; ; at least 1 string, followed by
181+ ; ; any number of keywords.
182+ (h/cat (h/repeat 1 3 (h/fn boolean?))
183+ (h/repeat 0 1 (h/fn int?))
184+ (h/repeat 1 ##Inf (h/fn string?))
185+ (h/repeat 0 ##Inf (h/fn keyword?)))
186+
187+ ; ; The same model, but written using shortcuts.
188+ (h/cat (h/repeat 1 3 (h/fn boolean?))
189+ (h/? (h/fn int?))
190+ (h/+ (h/fn string?))
191+ (h/* (h/fn keyword?)))
192+ ```
193+
194+ We can specify the type of collection used to contain a sequence.
195+
196+ ``` clojure
197+ ; ; A sequence of things which has to be inside a vector.
198+ (-> (h/cat (h/? (h/fn int?))
199+ (h/fn string?))
200+ h/in-vector)
201+
202+ ; ; Same model, but which has to be inside a list.
203+ (-> (h/cat (h/? (h/fn int?))
204+ (h/fn string?))
205+ h/in-list)
206+ ```
207+
208+ When a sequence is inside another sequence, it is considered inlined by default.
209+ With ` h/not-inlined ` , it will be contained in its own a collection (list or vector).
210+
211+ ``` clojure
212+ ; ; Matches '(1 2 3 "Soleil")
213+ (h/cat (h/+ (h/fn int?))
214+ (h/fn string?))
215+
216+ ; ; Matches '([1 2 3] "Soleil")
217+ (h/cat (-> (h/+ (h/fn int?))
218+ h/not-inlined)
219+ (h/fn string?))
220+ ```
221+
172222### Let / Ref
173223
174224` h/let ` creates a model where some local models are defined.
0 commit comments