% vim: set spelllang=nl:
\subsection{Semantiekregels}
\label{sec:cleansmurf:regels}
Iedere semantiekregel vertaalt min of meer direct naar een functiealternatief
voor \CI{step}. Echter, omdat we geen \CI{run}- maar een \CI{step}-functie
schrijven, moeten we compositie expliciet maken.

Als voorbeeld zullen we de implementatie van $\StmHead$ bekijken. Aangezien
\CI{pop} en \CI{head} allebei een \CI{Maybe} opleveren, kunnen we de resultaten
gemakkelijk binden. Vervolgens wordt de stack geüpdate en wordt de rest van het
programma (\CI{p}) teruggegeven. De IO-toestand wordt zonder gebruik
doorgegeven. Het vierde argument hebben we niet nodig en kan dus worden
genegeerd.

\lstinputlisting[firstline=213,lastline=215]{CleanSmurf/Smurf.icl}

Andere regels, voor $\StmPush$, $\StmTail$, $\StmCat$, $\StmQuotify$ en ook
$\StmPut$ en $\StmGet$ gaan op soortgelijke wijze. Ook $\StmInput$ en
$\StmOutput$ kunnen op dezelfde manier worden geschreven, afgezien van het feit
dat de IO-toestand en -functies gebruikt moeten worden.

In het geval van $\StmExec$ kunnen we handig gebruik maken van het feit dat
\CI{step} een nieuw programma oplevert:

\lstinputlisting[firstline=228,lastline=230]{CleanSmurf/Smurf.icl}

Zoals te zien wordt een nieuwe toestand gemaakt (\CI{zero}) waarin dit nieuwe
programma (\CI{p}) wordt uitgevoerd. De compositie \CI{parse o fromString}
parseert een String van de stack en levert een \CI{Maybe Program} op. Dus ook
deze wat afwijkende regel levert geen problemen op.
