phc-adt-variant.scrbl (6150B)
1 #lang scribble/manual 2 3 @(require racket/require 4 (for-label (subtract-in typed/racket/base type-expander) 5 type-expander 6 phc-adt 7 (lib "phc-adt/tagged.hl.rkt") 8 (lib "phc-adt/structure.hl.rkt") 9 (lib "phc-adt/constructor.hl.rkt") 10 (lib "phc-adt/variant.hl.rkt") 11 (lib "phc-adt/tagged-supertype.hl.rkt")) 12 scribble-enhanced/doc 13 scribble-math 14 (subtract-in scribble/struct scribble-enhanced/doc) 15 scribble/decode) 16 @doc-lib-setup 17 18 @title{Variants} 19 20 @deftech{Variants} behave like @racketmodname[typed/racket]'s union types 21 (expressed via @racket[U]). They benefit however of special support by the 22 graph library (not published yet), which needs to rewrite data structures 23 in-depth during the construction of the graph, and cannot handle arbitrary data 24 structures. 25 26 @defform[#:kind "type-expander" 27 #:literals (constructor tagged) 28 (variant maybe-check-overlap 29 constructor-or-taggedᵢ ... 30 maybe-one-other-type) 31 #:grammar 32 [(maybe-check-overlap (code:line) 33 (code:line #:check-overlap)) 34 (constructor-or-tagged (tagged tag-nameᵢ . tagged-args) 35 (structure . structure-args) 36 (constructor tag-nameᵢ . constructor-args)) 37 (constructor tag-name maybe-∀ τᵢ ... #:rest τ-rest) 38 (tag-nameᵢ Identifier) 39 (maybe-one-other-type (code:line) 40 (code:line Type))]]{ 41 The current implementation does not completely match this documentation, but 42 the implementation should shortly be updated. 43 44 Expands to the union type of all the given @tech{tagged structures}, @tech{ 45 untagged structures} and @tech{constructors}. 46 47 When another type which is not a tagged structure or similar is specified, 48 it is included in the union. Only one such type is allowed. 49 50 The types passed to @racket[variant] should not overlap. When the keyword 51 @racket[#:check-overlap] is specified, @racket[variant] uses a hack to throw 52 an error when two types overlap. The error message can however be unclear and 53 misleading, so this feature is disabled by default. 54 55 The elements of the grammar for @racket[define-tagged] may appear in any 56 order, as long as the @racket[constructor-or-taggedᵢ ... maybe-one-other-type] 57 form a contiguous sequence (the @racket[maybe-one-other-type] may occur at any 58 position within the sequence, but must be included at most once).} 59 60 @defidform[#:kind "type-expander" 61 V]{ 62 An alias for the @racket[variant] type expander. 63 } 64 65 @defform[#:kind "syntax" 66 #:literals (constructor tagged) 67 (variant? maybe-check-overlap 68 constructor-or-taggedᵢ ... 69 maybe-one-other-type) 70 #:grammar 71 [(maybe-check-overlap (code:line) 72 (code:line #:check-overlap)) 73 (constructor-or-tagged (tagged tag-nameᵢ . tagged-args) 74 (structure . structure-args) 75 (constructor tag-nameᵢ . constructor-args)) 76 (constructor tag-name maybe-∀ τᵢ ... #:rest τ-rest) 77 (tag-nameᵢ Identifier) 78 (maybe-one-other-type (code:line) 79 (code:line Type))]]{ 80 The current implementation does not completely match this documentation, but 81 the implementation should shortly be updated. 82 83 Expands to a predicate for the type: 84 85 @racketblock[(variant maybe-check-overlap 86 constructor-or-taggedᵢ ... 87 maybe-one-other-type)] 88 89 The elements of the grammar for @racket[variant] may appear in any order, as 90 long as the @racket[constructor-or-taggedᵢ ... maybe-one-other-type] form a 91 contiguous sequence (the @racket[maybe-one-other-type] may occur at any 92 position within the sequence, but must be included at most once).} 93 94 @defform[#:kind "syntax" 95 #:literals (:) 96 (define-variant name maybe-predicate? maybe-check-overlap cases) 97 #:grammar 98 [(name Identifier) 99 (maybe-predicate? (code:line) 100 (code:line #:? predicate-name?)) 101 (predicate-name? Identifier) 102 (maybe-check-overlap (code:line) 103 (code:line #:check-overlap)) 104 (cases (code:line constructor-or-taggedᵢ ... maybe-one-other-type)) 105 (constructor-or-tagged (tagged tag-nameᵢ . tagged-args) 106 (structure . structure-args) 107 (constructor tag-nameᵢ . constructor-args)) 108 (constructor tag-name maybe-∀ τᵢ ... #:rest τ-rest) 109 (tag-nameᵢ Identifier) 110 (maybe-one-other-type (code:line) 111 (code:line Type))]]{ 112 The current implementation does not completely match this documentation, but 113 the implementation should shortly be updated. 114 115 Defines @racket[name] as a shorthand for the type expander and predicate for 116 a variant with the given cases. 117 118 @(make-blockquote 119 "leftindent" 120 (flow-paragraphs 121 (decode-flow 122 (splice-run 123 @defidform[#:kind "type expander" 124 #:link-target? #f 125 _name]{ 126 Expands to the same type as @racket[(variant maybe-check-overlap cases)] 127 would.})))) 128 129 @(make-blockquote 130 "leftindent" 131 (flow-paragraphs 132 (decode-flow 133 (splice-run 134 @defidform[#:link-target? #f _predicate?]{ 135 136 Expands to the same predicate as @racket[(variant? maybe-check-overlap cases)] 137 would.})))) 138 139 The elements of the grammar for @racket[define-variant] may appear in any 140 order, as long as the @racket[constructor-or-taggedᵢ ... maybe-one-other-type] 141 form a contiguous sequence (the @racket[maybe-one-other-type] may occur at any 142 position within the sequence, but must be included at most once).}