Most GTK tutorials hand you a widget tree and a pile of callbacks and wish you luck. This one from Floréal Technologies does something more interesting: it uses the Elm Architecture (Model-View-Update) as the spine of a Haskell GTK 4 / Adwaita todo-list app, which means the domain logic lives entirely in pure functions and the imperative GTK layer becomes a rendering detail. That architectural commitment is the real content here, not the todo list. The setup is clean. You get haskell-gi for auto-generated bindings to GTK's C API, Adwaita for GNOME's design language (responsive layout, light/dark theme recoloring at runtime), and a project structure where Model, Message, Update, View, and Effects are all separate, typed data structures. The Model is a Map of Todos keyed by TodoId. Messages are a sum type (Add, SetDoneStatus). The update function is pure: it takes a Message and a Model and returns a new Model plus a list of Effects. No hidden state mutations. The GHCi session is the best part of the tutorial. The author drops into the REPL and demonstrates that adding a todo triggers a Save effect, setting a done status triggers another Save, and setting the same status again produces an empty effect list. This is the Elm Architecture's core promise made tangible: your entire state transition logic is testable without rendering a single pixel. For Haskellers used to property testing and equational reasoning, this is where the approach pays off. The View layer is more conventional — it's imperative GTK widget construction with Adwaita components (EntryRow, ActionRow, ListBox, Clamp, ScrolledWindow, ToolbarView). The dispatch function bridges the pure world and the imperative one: UI events become Messages, Messages feed into the pure update function, and the resulting Model gets rendered. The article acknowledges this is Part 1 and the runtime dispatch/step loop is only sketched. The widget selection is practical rather than flashy. ListBox for dynamic filtering and sorting, Clamp for responsive margins, ScrolledWindow for overflow. These are the Adwaita components that actually matter for non-trivial apps, and the tutorial picks them for functional reasons rather than showing off the full widget catalog. What's missing is meaningful: there's no persistence implementation (the Save effect is defined but not executed), no error handling, no discussion of performance with large todo lists, and the runtime loop connecting dispatch to step is cut off mid-sentence. This is explicitly Part 1, so those gaps are structural rather than oversights. The code is available at the linked GitHub repository. The intended audience is intermediate Haskellers with development experience in the language. If you don't already know what OverloadedLabels or deriving-via syntax means, this tutorial will not explain it. That's a reasonable scoping decision — the interesting content is the architecture pattern, not Haskell pedagogy.