Die Do-Notation ist die lesbare Kurzschreibweise für monadische Programme in Haskell. Statt verschachtelter >>=-Verkettungen schreibt man einen sequenziellen Block, in dem jede Zeile einen Schritt der Berechnung beschreibt.

Desugaring

Der Compiler übersetzt einen do-Block in verschachtelte bind-Aufrufe. Aus

do { x <- m; y <- n; return (x + y) }

wird

m >>= x -> n >>= y -> return (x + y)

Eine Zeile ohne Pfeil wird direkt als Ausdruck ausgewertet; let-Bindungen bleiben lokal. Damit ist die Do-Notation reiner Zucker — die Bedeutung legt immer die verwendete Monade fest, etwa die IO-Monade, die State-Monade oder die Listen-Monade, deren List-Comprehensions wie [x*y | x <- xs, y <- ys] genau dieselbe Struktur nutzen.

Besonderheiten

Die GHC-Erweiterung ApplicativeDo desugart Blöcke, die keine Abhängigkeiten zwischen den Schritten haben, zu applicative Operationen statt zu bind — das erlaubt mehr Parallelität und ist in allen gängigen Monaden semantisch gleichwertig. Muster wie Just x <- m binden an ein Pattern und schlagen fehl, wenn es nicht passt (MonadFail). Mit RebindableSyntax kann man >>=, >> und return neu definieren und die Do-Notation damit sogar für eigene Effekt-APIs wie Effect-TS verwenden. Dass Umformungen innerhalb eines do-Blocks das Verhalten nicht verändern, garantieren die Monaden-Gesetze. Weitere Praxis: Maybe-Monade (Pattern-Matching auf Just/Nothing), Haskell-Befehle.