Structs
Structs define record types with named fields, providing a convenient syntax for single-constructor types.
Basic Syntax
Structs are declared with the struct keyword:
struct Point {
x : I64,
y : I64
}
Field Default Values
Fields can have default values using :=:
struct Point3D {
x : I64,
y : I64,
z : I64 := 0
}
def origin := { x := 0, y := 0 }
// z defaults to 0
Linear and Affine Fields
Field access can be restricted with multiplicity annotations ! (linear, exactly once) or ? (affine, at most once):
struct Resource {
!handle : FileHandle, // linear — must be used exactly once
?label : String, // affine — may be unused
metadata : I64 // unrestricted (default)
}
Creating Struct Values
Struct values are created with brace syntax:
def origin := { x := 0, y := 0 }
def p := { x := 3, y := 4 }
Field Access
Access fields using dot notation:
def getX (p : Point) : I64 := p.x
def getY (p : Point) : I64 := p.y
Structs vs Types
A struct is equivalent to a single-constructor type. This struct:
struct Point {
x : I64,
y : I64
}
Is equivalent to:
type Point {
mk (x : I64) (y : I64)
}
Generic Structs
Structs can have type parameters:
struct Pair A B {
first : A,
second : B
}
def example := { first := "hello", second := 42 }
Pattern Matching on Structs
You can pattern match on struct constructors:
def swap (p : Point) : Point :=
match p {
mk x y => { x := y, y := x }
}
Summary
structdefines record types with named fields- Struct values use
{ field := value }syntax - Field access uses dot notation
- Structs are equivalent to single-constructor types
Next, we'll explore error handling patterns in Monad.