API reference

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 native Variant, 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's R.

Implements

CaseList

Aliases

  • Subject
  • count
  • Case

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 of F.

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 of F.

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 of F.

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 position i.

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 by R.

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.