fp.adt¶
fp.adt defines algebraic and inductive data types from ordinary Mojo structs.
Use Choice to store a non-recursive sum type in place, or Node for shared
values and recursive structures such as expression trees. Both support
exhaustive pattern matching through fp.matching.
The tutorial covers algebraic data and pattern matching, storage in place and inductive data types.
Algebraic data types declared from your own structs, and their values.
A data type lists its constructors, ordinary structs, in a Cases; a
constructor field that holds a value of the same type has the layer's
parameter R, List[R] or Optional[R]:
struct Expr(Data):
comptime Layer[R: Value] = Cases[Num, Add[R], If[R, R]]
A value holds one constructor, and comes in two kinds:
Node[F]is immutable and shared: copying it shares it in constant time. A node can only refer to nodes that already exist, so a value is a finite acyclic graph. Recursive data needs it; each node is one allocation.Choice[F]is owned and stored in place, in a nativeVariant, with no allocation, for a type with no recursive field. Copying it copies the constructor.
A constructor converts to either implicitly. fp.match matches both, and
fp.rewrite transforms nodes.
Summary¶
| Name | Kind | Summary |
|---|---|---|
Cases |
struct | The constructors of a data type, in declaration order. |
Choice |
struct | A value of a non-recursive data type F, stored in place: one of its constructors. |
Node |
struct | An immutable value of data type F: one constructor whose recursive fields hold Nodes. |
CaseList |
trait | The constructors of a data type in declaration order; implemented by Cases. |
Data |
trait | An algebraic data type: its constructors, with recursive positions typed by R. |
Value |
alias | The bound for constructor fields and results: values that can be moved and destroyed. |
Structs¶
Cases¶
Source: fp/adt/data.mojo
struct Cases[*Ts: Value](CaseList)
The constructors of a data type, in declaration order.
Parameters
*Ts(Value): The constructor structs; recursive fields use the layer'sR.
Implements
CaseList
Aliases
SubjectcountCase
Cases.get¶
def get[i: Int](ref subject: Subject) -> ref[subject] Case[i]
The constructor subject holds; it must be constructor i.
Parameters
i(Int): The constructor's position.
Arguments
subject(ref Subject): The stored value.
Returns
ref[subject] Case[i]: A reference to the stored constructor.
Cases.is_case¶
def is_case[i: Int](subject: Subject) -> Bool
Whether subject holds constructor i.
Parameters
i(Int): The constructor's position.
Arguments
subject(Subject): The stored value.
Returns
Bool: True when subject holds constructor i.
Cases.make¶
def make[i: Int](var value: Case[i]) -> Subject
Store constructor i.
Parameters
i(Int): The constructor's position.
Arguments
value(var Case[i]): The constructor, moved in.
Returns
Subject: The stored value.
Cases.take¶
def take[i: Int](var subject: Subject) -> Case[i]
Move out the constructor subject holds; it must be constructor i.
Parameters
i(Int): The constructor's position.
Arguments
subject(var Subject): The stored value, consumed.
Returns
Case[i]: The constructor, moved out.
Choice¶
Source: fp/adt/data.mojo
struct Choice[F: Data](
_ChoiceType,
Movable,
Copyable where conforms_to(F.Layer[Node[F]].Subject, Copyable),
ImplicitlyCopyable where conforms_to(F.Layer[Node[F]].Subject, ImplicitlyCopyable),
)
A value of a non-recursive data type F, stored in place: one of its constructors.
Unlike a Node, a Choice is owned, not shared: copying it copies the
constructor, and moving it moves it. It needs no allocation, and its
constructors need not be copyable; it is Copyable, or ImplicitlyCopyable,
when all of them are. A constructor converts to a Choice implicitly.
Parameters
F(Data): The data type; none of its fields is recursive.
Implements
Copyable, ImplicitlyCopyable, _ChoiceType
Aliases
Layer: The constructors.Of: The data type.
Choice.isa¶
def isa[C: AnyType](self) -> Bool
Whether the value is constructor C.
Parameters
C(AnyType): A constructor ofF.
Returns
Bool: True when the value holds C.
Choice.unwrap¶
def unwrap[C: Value](deinit self) -> C
Consume the value and return its constructor, which must be C.
Parameters
C(Value): A constructor ofF.
Returns
C: The stored constructor, moved out.
Node¶
Source: fp/adt/data.mojo
struct Node[F: Data](ImplicitlyCopyable, Movable, _NodeType)
An immutable value of data type F: one constructor whose recursive fields hold Nodes.
A Node can only refer to Nodes that already exist and cannot change after construction, so a Node and everything it reaches form a finite acyclic graph. Copying a Node shares it in constant time. Each Node stores its height, the longest path to a leaf, and is released in a loop, so values of any depth can be built and dropped.
Parameters
F(Data): The data type.
Implements
Copyable, ImplicitlyCopyable, _NodeType
Aliases
Layer: The stored constructors, with recursive fields holding Nodes.Of: The data type.
Node.isa¶
def isa[C: AnyType](self) -> Bool
Whether the value is constructor C (with Node children).
Parameters
C(AnyType): A constructor ofF.
Returns
Bool: True when the value holds C.
Traits¶
CaseList¶
Source: fp/adt/data.mojo
trait CaseList
The constructors of a data type in declaration order; implemented by Cases.
Associated aliases
Subject: The stored value: one constructor at a time.count: The number of constructors.Case: The constructor at positioni.
CaseList.get¶
def get[i: Int](ref subject: Subject) -> ref[subject] Case[i]
The constructor subject holds; it must be constructor i.
Parameters
i(Int): The constructor's position.
Arguments
subject(ref Subject): The stored value.
Returns
ref[subject] Case[i]: A reference to the stored constructor.
CaseList.is_case¶
def is_case[i: Int](subject: Subject) -> Bool
Whether subject holds constructor i.
Parameters
i(Int): The constructor's position.
Arguments
subject(Subject): The stored value.
Returns
Bool: True when subject holds constructor i.
CaseList.make¶
def make[i: Int](var value: Case[i]) -> Subject
Store constructor i.
Parameters
i(Int): The constructor's position.
Arguments
value(var Case[i]): The constructor, moved in.
Returns
Subject: The stored value.
CaseList.take¶
def take[i: Int](var subject: Subject) -> Case[i]
Move out the constructor subject holds; it must be constructor i.
Parameters
i(Int): The constructor's position.
Arguments
subject(var Subject): The stored value, consumed.
Returns
Case[i]: The constructor, moved out.
Data¶
Source: fp/adt/data.mojo
trait Data
An algebraic data type: its constructors, with recursive positions typed by R.
A recursive position is a field of type R, List[R] or Optional[R]. A
constructor may take several type parameters, so that a clause can treat its
fields differently; the layer passes R to each.
Associated aliases
Layer: The constructors with every recursive position filled byR.
Aliases¶
Value¶
Source: fp/adt/data.mojo
comptime Value = Movable & Deinitable
The bound for constructor fields and results: values that can be moved and destroyed.