Effect type.
The model
The model is any Haskell type you define. The only constraint is anEq instance so miso can detect when state has changed and avoid unnecessary redraws.
miso recommends using the derived
Eq instance. Custom Eq instances that return True too eagerly will prevent updates from being rendered.The view function
The view function is a pure function from model toView:
View is a rose-tree structure — the virtual DOM:
div_, button_, p_) build VNode values. Text nodes are created with text. Because View is a Functor, you can fmap over actions.
The update function
The update function handles every action and returns anEffect:
Effect is a monad that combines:
- State — modify the model with
put,modify, or lens operators - Writer — schedule IO actions for the miso scheduler
- Reader — access
ComponentInfo(the component’s ID, parent ID, and DOM reference)
There is no
MonadIO instance for Effect. IO is never evaluated inside Effect — it is only scheduled for the miso runtime to run later.Complete counter example
This is the canonical miso counter, taken directly from the library’s haddock documentation:The MVU cycle in detail
Event raised
The user interacts with the page. miso’s event delegator captures the browser event and routes it to the matching Haskell handler, which decodes it into an
action value (e.g. Add).Update called
The runtime calls
update action currentModel. The Effect monad accumulates state mutations and any scheduled IO.Model updated
The state mutations are applied, producing a new model. If it differs from the previous model (
Eq check), the view is recomputed.Diff and patch
miso diffs the new virtual DOM against the old one and applies the minimum set of DOM operations.
Pure by default, IO via Effect
Miso is pure by default. Side effects are introduced exclusively through theEffect type:
io_ schedules an IO () action asynchronously. The model is not modified. The scheduler runs the action after the current render cycle.
Comparison with React
| Concept | miso | React |
|---|---|---|
| State | model — a plain Haskell value | useState / class state |
| Rendering | view :: model -> View model action | render() / JSX function component |
| Events | Decoded action values, handled in update | Event handlers with setState |
| Side effects | Effect monad (scheduled, explicit) | useEffect (implicit, by dependency list) |
| Purity | Enforced — no MonadIO in Effect | Conventional — nothing stops imperative code |
| Component nesting | (+>) combinator, typed parent-child hierarchy | JSX element composition |