2.5 Singleton Types
(require rebellion/type/singleton) | package: rebellion |
A singleton type is a simple kind of data type made up of only one value. Singleton types are useful for representing named constants, such as the end-of-file marker value eof. Symbols can also be used for this purpose, but a singleton type is often preferable because misspelling the name of the constant causes a compile error rather than a silent bug at runtime.
(define-singleton-type undefined) (define/contract (divide x y) (-> real? real? (or/c real? undefined?)) (if (zero? y) undefined (/ x y)))
> (divide 6 3) 2
> (divide 6 0) #<undefined>
syntax
(define-singleton-type id singleton-option ...)
singleton-option = #:omit-root-binding | #:descriptor-name descriptor-id | #:predicate-name predicate-id | #:instance-name instance-id | #:property-maker prop-maker-expr | #:inspector inspector-expr
prop-maker-expr :
(-> uninitialized-singleton-descriptor? (listof (cons/c struct-type-property? any/c)))
inspector-expr : inspector?
instance-id, which defaults to instance:id —
the unique instance of the created type. predicate-id, which defaults to id? —
a predicate that returns #t when given the singleton instance and false for all other values. descriptor-id, which defaults to descriptor:id —
the type descriptor for the created type.
Additionally, unless #:omit-root-binding is specified, the original id is bound to a singleton type binding for the created type. The binding behaves like instance-id when used as an expression.
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-singleton-implementation for more information about these parameters.
(define-singleton-type infinity)
> infinity #<infinity>
> (infinity? infinity) #t
provide transformer
(singleton-out singleton)
2.5.1 Singleton Type Information
procedure
(singleton-type? v) → boolean?
v : any/c
procedure
(singleton-type name [ #:predicate-name predicate-name]) → singleton-type? name : interned-symbol? predicate-name : (or/c interned-symbol? #f) = #f
procedure
(singleton-type-name type) → interned-symbol?
type : singleton-type?
procedure
type : singleton-type?
2.5.2 Singleton Type Descriptors
Singleton types are implemented using fieldless structs, where only a single instance of the struct can be created. The type descriptor for a singleton type provides a predicate and, if the descriptor is initialized, can be used to retrieve the singleton instance.
procedure
v : any/c
procedure
v : any/c
procedure
v : any/c
procedure
(make-singleton-implementation type [ #:inspector inspector #:property-maker prop-maker]) → initialized-singleton-descriptor? type : singleton-type? inspector : inspector? = (current-inspector)
prop-maker :
(-> uninitialized-singleton-descriptor? (listof (cons/c struct-type-property? any/c))) = default-singleton-properties
procedure
(singleton-descriptor-type descriptor) → singleton-type?
descriptor : singleton-descriptor?
procedure
(singleton-descriptor-predicate descriptor) → predicate/c
descriptor : singleton-descriptor?
procedure
(singleton-descriptor-instance descriptor)
→ (singleton-descriptor-predicate descriptor) descriptor : initialized-singleton-descriptor?
procedure
(default-singleton-properties descriptor)
→ (listof (cons/c struct-type-property? any/c)) descriptor : singleton-descriptor?
This function is called by make-singleton-implementation when no prop-maker argument is supplied.
procedure
(default-singleton-custom-write descriptor)
→ custom-write-function/c descriptor : singleton-descriptor?
procedure
(default-singleton-object-name descriptor)
→ (or/c natural? (-> any/c any/c)) descriptor : singleton-descriptor?
2.5.3 Singleton Type Bindings
(require rebellion/type/singleton/binding) | |
package: rebellion |
A singleton type binding is a type binding for a singleton type. Singleton type bindings contain compile-time information about the singleton type’s name, as well as runtime bindings for its predicate, type descriptor, and instance. To extract a singleton type binding bound by define-singleton-type, use the singleton-id syntax class.
procedure
(singleton-binding? v) → boolean?
v : any/c
syntax class
type —
an attribute bound to a compile-time singleton-type? value describing the type. binding —
an attribute bound to the compile-time singleton-binding? value extracted from the matched identifier. name —
a pattern variable bound to the singleton type’s name, as a quoted symbol. descriptor —
a pattern variable bound to the singleton type’s runtime type descriptor. predicate —
a pattern variable bound to the singleton type’s runtime type predicate. instance —
a pattern variable bound to the singleton type’s runtime singleton instance.
(require (for-syntax rebellion/type/singleton/binding)) (define-simple-macro (singleton-predicate singleton:singleton-id) singleton.predicate) (define-singleton-type null)
> (singleton-predicate null) #<procedure:null?>
procedure
(singleton-binding-type binding) → singleton-type?
binding : singleton-binding?
procedure
(singleton-binding-descriptor binding) → identifier?
binding : singleton-binding?
procedure
(singleton-binding-predicate binding) → identifier?
binding : singleton-binding?
procedure
(singleton-binding-instance binding) → identifier?
binding : singleton-binding?