9 Enumerations (revised)
(require (planet untyped/unlib/enumeration)) |
Utilities for defining simple enumerations of booleans, symbols and integers. These are useful wherever you would normally use a small collection of literals to represent possible values of a variable, and test for value equality with eq?. The define-enum form binds the literals to Scheme identifiers so the compiler catches typos that might otherwise take a long time to debug.
(struct enum (name values pretty-values equality-test)) |
name : symbol? |
values : (listof (U boolean? symbol? integer?)) |
pretty-values : (listof string?) |
equality-test : (any any -> boolean?) |
An enumeration. For each symbol in values there is a human-readable string equivalent in pretty-values. equality-test (which is typically eq? is used to check for equality of pairs of values, and thus also for membership of the enumeration.
(define-enum enum-id (value-clause ...) keyword-arg ...) |
|
value-clause | | = | | value-id | | | | | | [value-id pretty-expr] | | | | | | [value-id value-expr pretty-expr] | | | | | | value-expr | | = | | any | | | | | | _ | | | | | | pretty-expr | | = | | string? | | | | | | keyword-arg | | = | | #:equality-test id |
|
Binds enum-id to an enumeration macro that can be used:
Examples: |
> (define-enum options | ([a 'option1 "first option"] | [b "second option"] | c)) |
|
> (options a) |
option1 |
> (options b) |
"second option" |
> (options c) |
c |
> (map (lambda (val) | (enum-prettify options val)) | (list (options a) (options b) (options c))) |
|
("first option" "b" "c") |
The identifier _ can be used as a value-expr as a shorthand for 'value-id. This is useful when writing value clauses where the value-id and the pretty-expr are the most important parts.
Examples: |
> (define-enum options | ([a _ "first option"] | [b _ "second option"] | [c _ "third option"])) |
|
> (options a) |
a |
> (options b) |
b |
> (options c) |
c |
> (map (lambda (val) | (enum-prettify options val)) | (list (options a) (options b) (options c))) |
|
("first option" "second option" "third option") |
Finally, the #:equality-test keyword can be used to specify the predicate that is used to check whether values belong to the enumeration. The default predicate is eq?.
(enum->string enum [separator]) → string? |
enum : enum? |
separator : string? = ", " |
Returns a string representation of (enum-values enum), useful for including in debugging output. separator is used to separate the enum values in the return value.
Examples: |
> (define-enum vehicle (car boat plane)) |
> (enum->string vehicle) |
"car, boat, plane" |
(enum->pretty-string enum [separator]) → string? |
enum : enum? |
separator : string? = ", " |
Returns a string representation of (enum-pretty-values enum), useful for describing the possible values to a user. separator is used to separate the enum values in the return value.
Examples: |
> (define-enum vehicle (car boat plane)) |
> (enum->pretty-string vehicle) |
"car, boat, plane" |
(enum-value? enum value) → boolean? |
enum : enum? |
value : any |
Returns #t if value is a member of (enum-values enum).
Examples: |
> (define-enum vehicle (car boat plane)) |
> (enum-value? vehicle 'car) |
#t |
> (enum-value? vehicle 'apple) |
#f |
(enum-same? enum value1 value2) → boolean? |
enum : enum? |
value1 : any |
value2 : any |
Uses the enum-equality-test in enum to determine if value1 and value2 are equal.
(enum-value/c enum) → flat-contract? |
enum : enum? |
Returns a contract that accepts values from (enum-values enum).
Like in-list but iterates through (enum-list enum val ...).
Examples: |
> (define-enum vehicle (car boat plane)) |
> (for/list ([val (in-enum vehicle)]) | val) |
|
(car boat plane) |
(for/list ([val (in-enum vehicle car plane)])
val)]
(in-enum/pretty enum val ...) |
Like in-list but iterates through the pretty versions of (enum-list enum val ...).
Examples: |
> (define-enum vehicle (car boat plane)) |
> (for/list ([val (in-enum/pretty vehicle)]) | val) |
|
("car" "boat" "plane") |
(for/list ([val (in-enum vehicle car plane)])
val)]
(enum-prettify enum value [default]) → string? |
enum : enum? |
value : symbol? |
| default | | : | | (U string? (-> string?)) | | | | = | | (cut raise-exn exn:fail:contract ...) |
|
Returns the pretty equivalent of value. If value is not found in enum, default is used instead:
if default is a procedure, it is called to determine the return value;
if default is not a procedure, it is returned.
(enum-list enum value ...) |
Expands to a list of values from enum.
Examples: |
> (define-enum vehicles (car boat plane)) |
> (enum-list vehicles car boat) |
(car boat) |
(enum-complement enum value ...) |
Expands to a list of all values in enum apart from the specified values.
Examples: |
> (define-enum vehicles (car boat plane)) |
> (enum-complement vehicles car boat) |
(plane) |
(enum-case enum value clause ...) |
|
clause | | = | | [(value ...) expr ...] | | | | | | [else expr ...] |
|
Like case but each value must be a value from enum. If an else expression is not provided, the values must cover the complete enumeration.
Examples: |
> (define-enum vehicles (car boat plane)) |
> (define (flies? vehicle) | (enum-case vehicles vehicle | [(plane) #t] | [(car boat) #f])) |
|
> (flies? 'car) |
#f |
> (flies? 'plane) |
#t |
(enum-lambda enum clause ...) |
|
clause | | = | | [(value ...) expr ...] | | | | | | [else expr ...] |
|
Expands to a procedure that accepts a single argument and runs enum-case on it.
Examples: |
> (define-enum vehicles (car boat plane)) |
> (define flies? | (enum-lambda vehicles | [(plane) #t] | [(car boat) #f])) |
|
> (flies? 'car) |
#f |
> (flies? 'plane) |
#t |
}