In de vorige oefening hebben we de basisinterpreter aangepast zodat hij betere foutboodschappen geeft. In deze oefening vertrekken we opnieuw van onze basisinterpreter en passen hem zodanig aan dat hij naast het evalueren van expressies ook zal bijhouden hoeveel evaluatiestappen hij hiervoor nodig heeft gehad. We tellen een stap als de evaluator een optelling uitvoert of een functie oproept.

In het onderstaande voorbeeld zijn er dus twee stappen aangezien de evaluator twee optellingen moet doen om tot het resultaat te komen.

> (Add (Add (Con 1) (Con 21)) (Con 20))
"Waarde: 42; Evaluatiestappen: 2"

Aangezien onze interpreter monadisch geïmplementeerd is kunnen we deze functionaliteit makkelijk toevoegen! Hieronder staat het datatype voor de state monad. Pas de rest van de code aan om het aantal evaluatiestappen bij te houden. Implementeer hiervoor de hulpfunctie tickS die het aantal evaluatiestappen met één zal verhogen.

-- De monad die we nu implementeren is de state monad en we houden nummers bij
type State = Int

-- De state monad is een functie van state naar een antwoord met een nieuwe state
type M a = State -> (a, State)

-- Verhoog het aantal evaluatie stappen met 1
tickS :: M ()