8. Pattern Matching #
8.1 Basic Patterns #
let result = match value {
0 => "zero"
1 => "one"
n => "other: " + toString(n)
}
8.2 Union Type Patterns #
type Option = Some { value: Int } | None
let message = match option {
Some x => "Value: " + toString(x.value)
None => "No value"
}
8.3 Wildcard Patterns #
The underscore _
matches any value:
let category = match score {
100 => "perfect"
90 => "excellent"
_ => "good"
}
8.4 Type Annotation Patterns #
Type annotation patterns use the :
operator to match values of specific types. This is REQUIRED for any
types.
type_pattern := ID ':' type
structural_pattern := ID ':' '{' field_list '}'
anonymous_structural_pattern := '{' field_list '}'
constructor_pattern := ID ('(' pattern (',' pattern)* ')')?
variable_pattern := ID
wildcard_pattern := '_'
Examples:
// Required for any types
match anyValue {
num: Int => num + 1
text: String => length(text)
flag: Bool => if flag then 1 else 0
_ => 0
}
// Structural matching - matches any type with these fields
match anyValue {
{ name, age } => print("${name}: ${age}") // Anonymous structural
p: { name, age } => print("Person ${p.name}: ${p.age}") // Named structural
u: User { id } => print("User ${id}") // Traditional typed
_ => print("Unknown")
}
// Advanced structural patterns
match anyValue {
{ x, y } => print("Point: (${x}, ${y})") // Any type with x, y fields
p: { name } => print("Named thing: ${p.name}") // Any type with name field
{ id, email, active: Bool } => print("Active user: ${id}") // Mixed field patterns
_ => print("No match")
}
// Type patterns with field destructuring
match result {
success: Success { value, timestamp } => processSuccess(value, timestamp)
error: Error { code, message } => handleError(code, message)
_ => defaultHandler()
}
Pattern Matching Features #
1. Type Annotation Patterns #
match anyValue {
i: Int => i * 2 // Bind as 'i' if Int
s: String => s + "!" // Bind as 's' if String
user: User => user.name // Bind as 'user' if User type
}
2. Anonymous Structural Matching #
Match on structure without requiring specific type names:
match anyValue {
{ name, age } => print("${name} is ${age}") // ANY type with name, age
{ x, y, z } => print("3D point: ${x},${y},${z}") // ANY type with x, y, z
{ id } => print("Has ID: ${id}") // ANY type with id field
}
3. Named Structural Matching #
Bind the whole object AND destructure fields:
match anyValue {
person: { name, age } => {
print("Person: ${person}") // Access whole object
print("Name: ${name}") // Access destructured field
print("Age: ${age}") // Access destructured field
}
point: { x, y } => calculateDistance(point, origin)
}
4. Mixed Type and Structural Patterns #
match anyValue {
user: User { id, name } => print("User ${id}: ${name}") // Explicit type
{ email, active } => print("Has email: ${email}") // Structural only
data: { values: Array<Int> } => processArray(data.values) // Nested types
_ => print("Unknown structure")
}
8.5 Result Type Pattern Matching (Arithmetic Expressions) #
🔥 CRITICAL: All arithmetic expressions return Result<T, MathError>
. You MUST handle them with pattern matching.
Simple Arithmetic Result Handling #
let calculation = 1 + 3 + (300 / 5) // Result<int, MathError>
match calculation {
Success { value } => print("Result: ${value}")
Error { message } => print("Math error: ${message}")
}
Compound Expression Examples (CRYSTAL CLEAR) #
// Each of these returns a SINGLE Result for the ENTIRE expression
let simple = 10 + 5 // Result<int, MathError>
let complex = 1 + 2 * 3 - 4 / 2 // Result<int, MathError>
let nested = ((a + b) * c) / (d - e) // Result<int, MathError>
// Handle ALL of them the SAME WAY
match simple {
Success { value } => print("10 + 5 = ${value}")
Error { message } => print("Failed: ${message}")
}
match complex {
Success { value } => print("Complex calc = ${value}")
Error { message } => print("Overflow/error: ${message}")
}
match nested {
Success { value } => print("Nested result = ${value}")
Error { message } => print("Division by zero or overflow: ${message}")
}
Function Return Results #
fn calculate(x: int, y: int) -> Result<int, MathError> = x + y * 2 - 5
let result = calculate(10, 3) // Result<int, MathError>
match result {
Success { value } => print("Function result: ${value}")
Error { message } => print("Function failed: ${message}")
}
Advanced Result Chains #
// Multiple Results in sequence
let step1 = 100 + 50 // Result<int, MathError>
let step2 = 200 * 3 // Result<int, MathError>
// Handle each step
match step1 {
Success { value1 } => {
match step2 {
Success { value2 } => {
let final = value1 + value2 // This is also Result<int, MathError>!
match final {
Success { total } => print("Final: ${total}")
Error { message } => print("Final calc failed: ${message}")
}
}
Error { message } => print("Step 2 failed: ${message}")
}
}
Error { message } => print("Step 1 failed: ${message}")
}