# Chapter 4: Data Types

Lux has algebraic data types (ADTs)—a powerful way to model data with variants and pattern matching.

## Defining Types

### Enums (Sum Types)

A type that can be one of several variants:

```lux
type Color =
    | Red
    | Green
    | Blue

let c: Color = Red
```

### Variants with Data

Variants can carry data:

```lux
type Shape =
    | Circle(Int)           // radius
    | Rectangle(Int, Int)   // width, height
    | Point

let s1 = Circle(5)
let s2 = Rectangle(10, 20)
let s3 = Point
```

### Named Fields

For clarity, use record variants:

```lux
type Person =
    | Person { name: String, age: Int }

let alice = Person { name: "Alice", age: 30 }
```

## Pattern Matching

The `match` expression destructures data:

```lux
fn colorName(c: Color): String =
    match c {
        Red => "red",
        Green => "green",
        Blue => "blue"
    }
```

### Extracting Data

```lux
fn area(s: Shape): Int =
    match s {
        Circle(r) => 3 * r * r,       // Approximate π as 3
        Rectangle(w, h) => w * h,
        Point => 0
    }

area(Circle(5))       // 75
area(Rectangle(4, 5)) // 20
```

### Exhaustiveness

The compiler ensures you handle all cases:

```lux
fn colorName(c: Color): String =
    match c {
        Red => "red",
        Green => "green"
        // Error: non-exhaustive pattern, missing Blue
    }
```

### Wildcard Pattern

Use `_` to match anything:

```lux
fn isRed(c: Color): Bool =
    match c {
        Red => true,
        _ => false       // Matches Green, Blue, anything else
    }
```

### Guards

Add conditions to patterns:

```lux
fn classify(n: Int): String =
    match n {
        0 => "zero",
        n if n > 0 => "positive",
        _ => "negative"
    }
```

### Nested Patterns

Match deep structures:

```lux
type Expr =
    | Num(Int)
    | Add(Expr, Expr)
    | Mul(Expr, Expr)

fn simplify(e: Expr): Expr =
    match e {
        Add(Num(0), x) => x,          // 0 + x = x
        Add(x, Num(0)) => x,          // x + 0 = x
        Mul(Num(0), _) => Num(0),     // 0 * x = 0
        Mul(_, Num(0)) => Num(0),     // x * 0 = 0
        Mul(Num(1), x) => x,          // 1 * x = x
        Mul(x, Num(1)) => x,          // x * 1 = x
        _ => e                         // No simplification
    }
```

## Built-in ADTs

### Option<T>

For optional values:

```lux
type Option<T> =
    | Some(T)
    | None
```

Usage:

```lux
fn safeDivide(a: Int, b: Int): Option<Int> =
    if b == 0 then None
    else Some(a / b)

fn showResult(opt: Option<Int>): String =
    match opt {
        Some(n) => "Result: " + toString(n),
        None => "Cannot divide by zero"
    }

showResult(safeDivide(10, 2))  // "Result: 5"
showResult(safeDivide(10, 0))  // "Cannot divide by zero"
```

### Result<T, E>

For operations that can fail with an error:

```lux
type Result<T, E> =
    | Ok(T)
    | Err(E)
```

Usage:

```lux
fn parseAge(s: String): Result<Int, String> =
    // Simplified - assume we have a real parser
    if s == "42" then Ok(42)
    else Err("Invalid age: " + s)

fn handleAge(r: Result<Int, String>): String =
    match r {
        Ok(age) => "Age is " + toString(age),
        Err(msg) => "Error: " + msg
    }
```

### List<T>

Lists are built-in but conceptually:

```lux
type List<T> =
    | Nil
    | Cons(T, List<T>)
```

Pattern match on lists:

```lux
fn sum(nums: List<Int>): Int =
    match nums {
        [] => 0,
        [x, ...rest] => x + sum(rest)
    }

fn length<T>(list: List<T>): Int =
    match list {
        [] => 0,
        [_, ...rest] => 1 + length(rest)
    }
```

## Recursive Types

Types can reference themselves:

```lux
type Tree<T> =
    | Leaf(T)
    | Node(Tree<T>, Tree<T>)

fn sumTree(t: Tree<Int>): Int =
    match t {
        Leaf(n) => n,
        Node(left, right) => sumTree(left) + sumTree(right)
    }

let tree = Node(Node(Leaf(1), Leaf(2)), Leaf(3))
sumTree(tree)  // 6
```

## Type Aliases

Give names to existing types:

```lux
type UserId = Int
type Username = String
type UserMap = List<(UserId, Username)>
```

## Records

Anonymous record types:

```lux
let point = { x: 10, y: 20 }
point.x  // 10
point.y  // 20

// With type annotation
type Point = { x: Int, y: Int }
let p: Point = { x: 5, y: 10 }
```

### Record Update

Create new records based on existing ones:

```lux
let p1 = { x: 10, y: 20 }
let p2 = { ...p1, x: 15 }  // { x: 15, y: 20 }
```

## Practical Example: Expression Evaluator

```lux
type Expr =
    | Num(Int)
    | Add(Expr, Expr)
    | Sub(Expr, Expr)
    | Mul(Expr, Expr)
    | Div(Expr, Expr)

fn eval(e: Expr): Result<Int, String> =
    match e {
        Num(n) => Ok(n),
        Add(a, b) => {
            match (eval(a), eval(b)) {
                (Ok(x), Ok(y)) => Ok(x + y),
                (Err(e), _) => Err(e),
                (_, Err(e)) => Err(e)
            }
        },
        Sub(a, b) => {
            match (eval(a), eval(b)) {
                (Ok(x), Ok(y)) => Ok(x - y),
                (Err(e), _) => Err(e),
                (_, Err(e)) => Err(e)
            }
        },
        Mul(a, b) => {
            match (eval(a), eval(b)) {
                (Ok(x), Ok(y)) => Ok(x * y),
                (Err(e), _) => Err(e),
                (_, Err(e)) => Err(e)
            }
        },
        Div(a, b) => {
            match (eval(a), eval(b)) {
                (Ok(_), Ok(0)) => Err("Division by zero"),
                (Ok(x), Ok(y)) => Ok(x / y),
                (Err(e), _) => Err(e),
                (_, Err(e)) => Err(e)
            }
        }
    }

// (10 + 5) * 2
let expr = Mul(Add(Num(10), Num(5)), Num(2))
eval(expr)  // Ok(30)

// 10 / 0
let bad = Div(Num(10), Num(0))
eval(bad)  // Err("Division by zero")
```

## Summary

| Concept | Syntax | Example |
|---------|--------|---------|
| Enum | `type T = \| A \| B` | `type Bool = \| True \| False` |
| With data | `\| Variant(Type)` | `\| Some(Int)` |
| Match | `match x { ... }` | `match opt { Some(n) => n, None => 0 }` |
| Wildcard | `_` | `_ => "default"` |
| Guard | `pattern if cond` | `n if n > 0 => "positive"` |
| Record | `{ field: value }` | `{ x: 10, y: 20 }` |

## Next

[Chapter 5: Effects](05-effects.md) - The core innovation of Lux.
