On this page:
variant?
variant
variant-value
variant-tag
variant-tagged-as?
variant/  c
7.7

1.8 Variants

 (require rebellion/base/variant) package: rebellion

A variant is a value tagged with a keyword. Variants are used to distinguish different kinds of values by name, without knowing anything about the types of those values.

procedure

(variant? v)  variant?

  v : any/c
A predicate for variants.

procedure

(variant #:<kw> v)  variant?

  v : any/c
Constructs a variant containing v tagged with the given keyword, where #:<kw> stands for any keyword.

Examples:
> (variant #:success 42)

(variant #:success 42)

> (variant #:failure "oops")

(variant #:failure "oops")

Additionally, the variant constructor may be used as a match expander.

Examples:
(define (try-add1 v)
  (match v
    [(variant #:success x) (add1 x)]
    [(variant #:failure msg) (error msg)]))

 

> (try-add1 (variant #:success 42))

43

> (try-add1 (variant #:failure "oops"))

oops

procedure

(variant-value var)  any/c

  var : variant?
Returns the value contained in var.

Examples:
> (variant-value (variant #:success 42))

42

> (variant-value (variant #:failure "oops"))

"oops"

procedure

(variant-tag var)  keyword?

  var : variant?
Returns the tag keyword of var.

Examples:
> (variant-tag (variant #:success 42))

'#:success

> (variant-tag (variant #:failure "oops"))

'#:failure

procedure

(variant-tagged-as? var tag-keyword)  boolean?

  var : variant?
  tag-keyword : keyword?
Returns #t if var is tagged with tag-keyword, returns #f otherwise.

Examples:
> (variant-tagged-as? (variant #:success 42) '#:success)

#t

> (variant-tagged-as? (variant #:success 42) '#:failure)

#f

procedure

(variant/c #:<kw> case-contract ...)  contract?

  case-contract : contract?
A contract combinator for variants. Returns a contract that enforces that the contracted value is a variant tagged with one of the given #:<kw>s. If it is, then the corresponding case-contract is used to check the variant’s value. If every case-contract is a flat contract then the returned contract is as well, and likewise for chaperone contracts.

Examples:
(define/contract (get-success-or-zero var)
  (-> (variant/c #:success number? #:failure string?) number?)
  (match var
    [(variant #:success x) x]
    [(variant #:failure _) 0]))

 

> (get-success-or-zero (variant #:success 42))

42

> (get-success-or-zero (variant #:success "not a number"))

get-success-or-zero: contract violation

  expected: number?

  given: "not a number"

  in: the #:success case of

      the 1st argument of

      (->

       (variant/c

        #:failure

        string?

        #:success

        number?)

       number?)

  contract from:

      (function get-success-or-zero)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2.0

> (get-success-or-zero (variant #:other "whoops"))

get-success-or-zero: contract violation

  expected: a variant with tag #:failure or #:success

  given: (variant #:other "whoops")

  in: the 1st argument of

      (->

       (variant/c

        #:failure

        string?

        #:success

        number?)

       number?)

  contract from:

      (function get-success-or-zero)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:2.0