On this page:
variant
V
variant?
define-variant
7.1

4 Variants

Variants behave like typed/racket’s union types (expressed via U). They benefit however of special support by the graph library (not published yet), which needs to rewrite data structures in-depth during the construction of the graph, and cannot handle arbitrary data structures.

type-expander

(variant maybe-check-overlap
         constructor-or-taggedᵢ ...
         maybe-one-other-type)
 
maybe-check-overlap = 
  | #:check-overlap
     
constructor-or-tagged = (tagged      tag-nameᵢ . tagged-args)
  | (structure             . structure-args)
  | (constructor tag-nameᵢ . constructor-args)
     
constructor = tag-name
  | maybe-∀
  | τᵢ
  | ...
  | #:rest
  | τ-rest
     
tag-nameᵢ = Identifier
     
maybe-one-other-type = 
  | Type
The current implementation does not completely match this documentation, but the implementation should shortly be updated.

Expands to the union type of all the given tagged structures, untagged structures and constructors.

When another type which is not a tagged structure or similar is specified, it is included in the union. Only one such type is allowed.

The types passed to variant should not overlap. When the keyword #:check-overlap is specified, variant uses a hack to throw an error when two types overlap. The error message can however be unclear and misleading, so this feature is disabled by default.

The elements of the grammar for define-tagged may appear in any order, as long as the constructor-or-taggedᵢ ... maybe-one-other-type form a contiguous sequence (the maybe-one-other-type may occur at any position within the sequence, but must be included at most once).

type-expander

V

An alias for the variant type expander.

syntax

(variant? maybe-check-overlap
          constructor-or-taggedᵢ ...
          maybe-one-other-type)
 
maybe-check-overlap = 
  | #:check-overlap
     
constructor-or-tagged = (tagged      tag-nameᵢ . tagged-args)
  | (structure             . structure-args)
  | (constructor tag-nameᵢ . constructor-args)
     
constructor = tag-name
  | maybe-∀
  | τᵢ
  | ...
  | #:rest
  | τ-rest
     
tag-nameᵢ = Identifier
     
maybe-one-other-type = 
  | Type
The current implementation does not completely match this documentation, but the implementation should shortly be updated.

Expands to a predicate for the type:

(variant maybe-check-overlap
         constructor-or-taggedᵢ ...
         maybe-one-other-type)

The elements of the grammar for variant may appear in any order, as long as the constructor-or-taggedᵢ ... maybe-one-other-type form a contiguous sequence (the maybe-one-other-type may occur at any position within the sequence, but must be included at most once).

syntax

(define-variant name maybe-predicate? maybe-check-overlap cases)

 
name = Identifier
     
maybe-predicate? = 
  | #:? predicate-name?
     
predicate-name? = Identifier
     
maybe-check-overlap = 
  | #:check-overlap
     
cases = constructor-or-taggedᵢ ... maybe-one-other-type
     
constructor-or-tagged = (tagged      tag-nameᵢ . tagged-args)
  | (structure             . structure-args)
  | (constructor tag-nameᵢ . constructor-args)
     
constructor = tag-name
  | maybe-∀
  | τᵢ
  | ...
  | #:rest
  | τ-rest
     
tag-nameᵢ = Identifier
     
maybe-one-other-type = 
  | Type
The current implementation does not completely match this documentation, but the implementation should shortly be updated.

Defines name as a shorthand for the type expander and predicate for a variant with the given cases.

type expander

name

Expands to the same type as (variant maybe-check-overlap cases) would.

syntax

predicate?

Expands to the same predicate as (variant? maybe-check-overlap cases) would.

The elements of the grammar for define-variant may appear in any order, as long as the constructor-or-taggedᵢ ... maybe-one-other-type form a contiguous sequence (the maybe-one-other-type may occur at any position within the sequence, but must be included at most once).