On this page:
define-enum-type
enum-out
2.4.1 Enum Type Information
enum-type?
enum-type
enum-type-name
enum-type-constants
enum-type-predicate-name
enum-type-discriminator-name
enum-type-selector-name
enum-type-size
2.4.2 Enum Type Descriptors
enum-descriptor?
initialized-enum-descriptor?
uninitialized-enum-descriptor?
make-enum-implementation
enum-descriptor-type
enum-descriptor-predicate
enum-descriptor-selector
enum-descriptor-discriminator
default-enum-properties
default-enum-equal+  hash
default-enum-custom-write
default-enum-object-name
2.4.3 Enum Type Bindings
enum-binding?
enum-id
enum-binding-type
enum-binding-constants
enum-binding-descriptor
enum-binding-predicate
enum-binding-selector
enum-binding-discriminator
8.0

2.4 Enum Types

 (require rebellion/type/enum) package: rebellion

An enum type is a simple kind of data type made up of a small fixed set of named values. Enum types are useful for representing groups of related constants, such as primary colors and directions.

Examples:
(define-enum-type direction (up down left right))
(define-tuple-type point (x y))
 
(define/contract (point-move pt dir amount)
  (-> point? direction? real? point?)
  (match-define (point x y) pt)
  (match dir
    [(== up) (point x (+ y amount))]
    [(== down) (point x (- y amount))]
    [(== left) (point (- x amount) y)]
    [(== right) (point (+ x amount) y)]))

 

> (point-move (point 2 2) up 5)

(point 2 7)

> (point-move (point 1 4) left 10)

(point -9 4)

> (point-move (point 1 4) 'up 5)

point-move: contract violation

  expected: direction?

  given: 'up

  in: the 2nd argument of

      (-> point? direction? real? point?)

  contract from: (function point-move)

  blaming: top-level

   (assuming the contract is correct)

  at: eval:4.0

syntax

(define-enum-type id (constant-id ...) enum-option ...)

 
enum-option = #:omit-root-binding
  | #:descriptor-name descriptor-id
  | #:predicate-name predicate-id
  | #:discriminator-name discriminator-id
  | #:selector-name selector-id
  | #:property-maker prop-maker-expr
  | #:inspector inspector-expr
 
  prop-maker-expr : 
(-> uninitialized-enum-descriptor?
    (listof (cons/c struct-type-property? any/c)))
  inspector-expr : inspector?
Creates an enum type named id and binds the following identifiers:

Additionally, unless #:omit-root-binding is specified, the original id is bound to an enum type binding for the created type.

The prop-maker-expr is used to add structure type properties to the created type, and inspector-expr is used to determine the inspector that will control the created type. See make-enum-implementation for more information about these parameters.

Examples:
(define-enum-type suit (diamonds clubs hearts spades))
(define-enum-type face (jack queen king))
(define-tuple-type card (type suit))
 
(define king-of-clubs (card king clubs))

 

> (card-type king-of-clubs)

#<face:king>

> (card-suit king-of-clubs)

#<suit:clubs>

 

(define/contract (card-value c)
  (-> card? (integer-in 1 13))
  (match (card-type c)
    [(? number? x) x]
    [(== jack) 11]
    [(== queen) 12]
    [(== king) 13]))

 

> (card-value king-of-clubs)

13

> (card-value (card 7 spades))

7

> (card-value (card jack hearts))

11

provide transformer

(enum-out enum)

Provides enum, which must be an enum-id, along with its predicate and constants.

2.4.1 Enum Type Information

procedure

(enum-type? v)  boolean?

  v : any/c
A predicate for enum types.

procedure

(enum-type name 
  constants 
  [#:predicate-name predicate-name 
  #:discriminator-name discriminator-name] 
  #:selector-name selector-name) 
  enum-type?
  name : interned-symbol?
  constants : keyset?
  predicate-name : (or/c interned-symbol? #f) = #f
  discriminator-name : (or/c interned-symbol? #f) = #f
  selector-name : (or/c interned-symbol? #f)
Constructs an enum type named name and containing constants. The optional predicate-name, discriminator-name, and selector-name arguments control the result of object-name on the functions implementing the type. They default to name?, discriminator:name, and selector:name respectively. This function only constructs the information representing an enum type; to implement the type, use make-enum-implementation.

Example:
> (enum-type 'weather (keyset #:sunny #:cloudy #:raining #:snowing))

(enum-type

 'weather

 (keyset #:cloudy #:raining #:snowing #:sunny)

 'weather?

 'discriminator:weather

 'selector:weather)

procedure

(enum-type-name type)  interned-symbol?

  type : enum-type?

procedure

(enum-type-constants type)  keyset?

  type : enum-type?

procedure

(enum-type-predicate-name type)  interned-symbol?

  type : enum-type?

procedure

(enum-type-discriminator-name type)  interned-symbol?

  type : enum-type?

procedure

(enum-type-selector-name type)  interned-symbol?

  type : enum-type?
Accessors for the various components of an enum type.

procedure

(enum-type-size type)  natural?

  type : enum-type?
Returns the number of enum constants in type.

2.4.2 Enum Type Descriptors

Enum types are implemented by representing each constant in the enum with an integer. The type descriptor of an enum type has contains two functions for dynamically inspecting this mapping:

These two functions are inverses of each other. Assuming the enum descriptor is initialized, these functions can be used to dynamically convert between integers and enum constants. To convert between strings or symbols and enum constants, use the integers in conjunction with enum-type-constants. Note that the constants of an enum type are stored in a keyset, so they are always in alphabetical order.

procedure

(enum-descriptor? v)  boolean?

  v : any/c
A predicate for enum type descriptors.

procedure

(initialized-enum-descriptor? v)  boolean?

  v : any/c
A predicate for initialized enum type descriptors.

procedure

(uninitialized-enum-descriptor? v)  boolean?

  v : any/c
A predicate for uninitialized enum type descriptors.

procedure

(make-enum-implementation type 
  [#:inspector inspector 
  #:property-maker prop-maker]) 
  initialized-enum-descriptor?
  type : enum-type?
  inspector : inspector? = (current-inspector)
  prop-maker : 
(-> uninitialized-enum-descriptor?
    (listof (cons/c struct-type-property? any/c)))
   = default-enum-properties
Implements type and returns a type descriptor for the new implementation. The inspector argument behaves the same as in make-struct-type, although there are no transparent or prefab enum types. The prop-maker argument is similar to the corresponding argument of make-struct-implementation. By default, enum types are created with properties that make them print like other named Racket constants such as eof see default-enum-properties for details.

Examples:
(define descriptor:weather
  (make-enum-implementation
   (enum-type 'weather (keyset #:sunny #:cloudy #:raining #:snowing))))
(define weather? (enum-descriptor-predicate descriptor:weather))
(define discriminator:weather
  (enum-descriptor-discriminator descriptor:weather))
(define selector:weather (enum-descriptor-selector descriptor:weather))

 

> (selector:weather 0)

#<weather:cloudy>

> (selector:weather 1)

#<weather:raining>

 

(define cloudy (selector:weather 0))

 

> (weather? cloudy)

#t

> (discriminator:weather cloudy)

0

procedure

(enum-descriptor-type descriptor)  enum-type?

  descriptor : enum-descriptor?
Returns the enum type that descriptor implements.

procedure

(enum-descriptor-predicate descriptor)  predicate/c

  descriptor : enum-descriptor?
Returns a predicate that returns true when given any enum constant created by descriptor. The predicate is specific to descriptor it will not return true for constants created by any other enum descriptors, even if they’re different implementations of the same enum type as descriptor. This is because enum types are nominal types.

procedure

(enum-descriptor-selector descriptor)

  (-> natural? (enum-descriptor-predicate descriptor))
  descriptor : enum-descriptor?
Returns the enum selector of the enum type implementation represented by descriptor. The selector accepts a nonnegative integer less than the number of enum constants in descriptor and returns the corresponding constant.

procedure

(enum-descriptor-discriminator descriptor)

  (-> (enum-descriptor-predicate descriptor) natural?)
  descriptor : enum-descriptor?
Returns the enum selector of the enum type implementation represented by descriptor. The selector accepts any enum constant created by descriptor and returns that constant’s integer representation.

procedure

(default-enum-properties descriptor)

  (listof (cons/c struct-type-property? any/c))
  descriptor : enum-descriptor?
Returns implementations of prop:equal+hash, prop:object-name, and prop:custom-write suitable for most enum types. This function is called by make-enum-implementation when no prop-maker argument is supplied.

procedure

(default-enum-equal+hash descriptor)  equal+hash/c

  descriptor : enum-descriptor?
Builds an equality-checking function, a hashing function, and a secondary hashing function suitable for use with prop:equal+hash, each of which operate on enum constants created by descriptor. Two constants are equal if and only if they are the same constant. This function is used by default-enum-properties to implement prop:equal+hash.

procedure

(default-enum-custom-write descriptor)

  custom-write-function/c
  descriptor : enum-descriptor?
Builds a custom write implementation that prints enum constants created by descriptor in a manner similar to built-in Racket constants, such as eof. The printed representations include both the name of the enum type and the name of the enum constant. This function is used by default-enum-properties to implement prop:custom-write.

procedure

(default-enum-object-name descriptor)

  (or/c natural? (-> any/c any/c))
  descriptor : enum-descriptor?
Builds a value suitable for use with prop:object-name that causes object-name to return the name of the constant when used on enum constants created by descriptor. This function is used by default-enum-properties to implement prop:object-name.

2.4.3 Enum Type Bindings

 (require rebellion/type/enum/binding)
  package: rebellion

An enum type binding is a type binding for an enum type. Enum type bindings contain compile-time information about the enum type’s name and values, as well as runtime bindings for its predicate, type descriptor, and other runtime components. To extract an enum type binding bound by define-enum-type, use the enum-id syntax class.

procedure

(enum-binding? v)  boolean?

  v : any/c
A predicate for enum type bindings.

syntax class

enum-id

A syntax class for enum type bindings bound by define-enum-type. This class matches any identifier bound with define-syntax to a value satisfying the enum-binding? predicate, similar to the static syntax class. Upon a successful match, the enum-id class defines the following attributes:

Examples:
(require (for-syntax rebellion/type/enum/binding))
 
(define-simple-macro (enum-names enum:enum-id)
  (list enum.constant-name ...))
 
(define-enum-type compass-direction (north south east west))

 

> (enum-names compass-direction)

'(east north south west)

procedure

(enum-binding-type binding)  enum-type?

  binding : enum-binding?
Returns the enum type that binding is for. When an enum type binding is bound with define-syntax, this can be used at compile-time to obtain information about the size and names of the enum type.

procedure

(enum-binding-constants binding)

  (vectorof identifier? #:immutable #t)
  binding : enum-binding?
Returns a vector of identifiers bound at runtime to the constants of the enum type bound by binding. When an enum type binding is bound with define-syntax, this can be used by macros to generate a list of the enum’s constants in code. The returned identifiers are sorted alphabetically.

procedure

(enum-binding-descriptor binding)  identifier?

  binding : enum-binding?
Returns an identifier that is bound at runtime to the type descriptor for the enum type bound by binding. When an enum type binding is bound with define-syntax, this can be used in macro-generated code to work with enum types dynamically.

procedure

(enum-binding-predicate binding)  identifier?

  binding : enum-binding?
Returns an identifier that is bound at runtime to the predicate for the enum type bound by binding.

procedure

(enum-binding-selector binding)  identifier?

  binding : enum-binding?
Returns an identifier that is bound at runtime to the enum selector for the enum type bound by binding.

procedure

(enum-binding-discriminator binding)  identifier?

  binding : enum-binding?
Returns an identifier that is bound at runtime to the enum discriminator for the enum type bound by binding.