structured_data.adt¶
Base classes for defining abstract data types.
This module provides three public members, which are used together.
Given a structure, possibly a choice of different structures, that you’d like to associate with a type:
- First, create a class, that subclasses the Sum class.
- Then, for each possible structure, add an attribute annotation to the class
with the desired name of the constructor, and a type of
Ctor
, with the types within the constructor as arguments.
To look inside an ADT instance, use the functions from the
structured_data.match
module.
Putting it together:
>>> from structured_data import match
>>> class Example(Sum):
... FirstConstructor: Ctor[int, str]
... SecondConstructor: Ctor[bytes]
... ThirdConstructor: Ctor
... def __iter__(self):
... matchable = match.Matchable(self)
... if matchable(Example.FirstConstructor(match.pat.count, match.pat.string)):
... count, string = matchable[match.pat.count, match.pat.string]
... for _ in range(count):
... yield string
... elif matchable(Example.SecondConstructor(match.pat.bytes)):
... bytes_ = matchable[match.pat.bytes]
... for byte in bytes_:
... yield chr(byte)
... elif matchable(Example.ThirdConstructor()):
... yield "Third"
... yield "Constructor"
>>> list(Example.FirstConstructor(5, "abc"))
['abc', 'abc', 'abc', 'abc', 'abc']
>>> list(Example.SecondConstructor(b"abc"))
['a', 'b', 'c']
>>> list(Example.ThirdConstructor())
['Third', 'Constructor']
-
class
structured_data.adt.
Ctor
[source]¶ Marker class for adt constructors.
To use, index with a sequence of types, and annotate a variable in an adt-decorated class with it.
-
class
structured_data.adt.
Product
[source]¶ Base class of classes with typed fields.
Examines PEP 526 __annotations__ to determine fields.
If repr is true, a __repr__() method is added to the class. If order is true, rich comparison dunder methods are added.
The Product class examines the class to find annotations. Annotations with a value of “None” are discarded. Fields may have default values, and can be set to inspect.empty to indicate “no default”.
The subclass is subclassable. The implementation was designed with a focus on flexibility over ideals of purity, and therefore provides various optional facilities that conflict with, for example, Liskov substitutability. For the purposes of matching, each class is considered distinct.
-
class
structured_data.adt.
Sum
[source]¶ Base class of classes with disjoint constructors.
Examines PEP 526 __annotations__ to determine subclasses.
If repr is true, a __repr__() method is added to the class. If order is true, rich comparison dunder methods are added.
The Sum class examines the class to find Ctor annotations. A Ctor annotation is the adt.Ctor class itself, or the result of indexing the class, either with a single type hint, or a tuple of type hints. All other annotations are ignored.
The subclass is not subclassable, but has subclasses at each of the names that had Ctor annotations. Each subclass takes a fixed number of arguments, corresponding to the type hints given to its annotation, if any.