— user@ocaml-programming —
user@ocaml-programming $ cat ./ocaml-programming.md (main)

ocaml-programming

# OCaml für die Praxis — eine Tutorial-Reihe.

~/ / docs / Grundlagen / 05 · Grundlagen

Listen, Records, Varianten

Die drei Datenstrukturen, die in nahezu jedem OCaml-Programm auftauchen — mit den passenden Pattern-Matching-Idiomen.

Drei Datentypen prägen idiomatischen OCaml-Code: Listen für Sequenzen, Records für benannte Felder, Varianten für Alternativen. Jeder hat sein typisches Einsatzfeld — und passt nahtlos mit Pattern Matching zusammen.

Listen

OCaml-Listen sind einfach verkettet, homogen (alle Elemente derselbe Typ) und immutabel. Konstruktion mit ::, der leeren Liste [] oder der Literalsyntax:

let nums = [1; 2; 3; 4]
let nums' = 1 :: 2 :: 3 :: 4 :: []

Die übliche Verarbeitung ist rekursiv mit Pattern Matching auf Kopf und Rest:

let rec sum = function
  | []      -> 0
  | x :: xs -> x + sum xs

function ist eine Kurzform für fun x -> match x with. In der Praxis greift man oft direkt zur Standardbibliothek:

utop # List.length [1; 2; 3] ;;
- : int = 3

utop # List.map (fun x -> x * x) [1; 2; 3] ;;
- : int list = [1; 4; 9]

Records

Records gruppieren benannte Felder. Sie müssen vor Gebrauch deklariert werden:

type person = {
  name : string;
  age  : int;
  city : string;
}

let alice = { name = "Alice"; age = 30; city = "Berlin" }

Felder werden mit Punkt-Notation gelesen. Für „aktualisierte” Kopien gibt es die with-Syntax — der ursprüngliche Record bleibt unverändert:

let alice_in_munich = { alice with city = "München" }

Pattern Matching funktioniert auch auf Records, oft beim Argument-Destrukturieren:

let greet { name; _ } = "Hallo, " ^ name

Das _ am Ende sagt: „weitere Felder ignorieren, mich interessiert nur name”.

Varianten

Varianten — auch Summentypen — beschreiben einen Wert, der eine von mehreren Formen annehmen kann. Jede Form bekommt einen Konstruktor:

type shape =
  | Circle of float
  | Rectangle of float * float
  | Triangle of { base : float; height : float }

Die Behandlung erfolgt fast immer mit match:

let area = function
  | Circle r -> 3.14159 *. r *. r
  | Rectangle (w, h) -> w *. h
  | Triangle { base; height } -> 0.5 *. base *. height

Der Compiler garantiert, dass alle Konstruktoren behandelt werden. Kommt später Pentagon of float dazu, weisen alle unvollständigen Matches sofort auf — eine harte Refactoring-Stütze.

Varianten ohne Daten heißen Aufzählungen:

type color = Red | Green | Blue

Mit diesen drei Bausteinen modelliert man fast jede Domäne sauber. Im nächsten Kapitel geht es um zwei Standardvarianten: Option und Result — die idiomatische Art, Fehlerfälle zu behandeln.