You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
eval1 expr = case expr of<br />
Succ t -> Succ (eval1 t)<br />
Pred Zero<br />
-> Just Zero<br />
Pred (Succ t) | isNum t -> Just t<br />
Pred t -> Pred (eval1 t)<br />
IsZero Zero<br />
-> Just Tr<br />
IsZero (Succ t) | isNum t -> Just Fl<br />
IsZero t -> IsZero (eval1 t)<br />
If Tr c _ -> Just c<br />
If Fl _ a<br />
-> Just a<br />
If t c a<br />
-> (\t’ -> If t’ c a) eval1 t<br />
_<br />
-> Nothing<br />
As we noticed before we could construct all sorts of pathological expressions that would become stuck.<br />
Looking at the evaluation rules, each of the guarded pattern matches gives us a hint of where things<br />
might “go wrong” whenever a boolean is used in the place of a number and vice versa. We’d like to<br />
statically enforce this invariant at compile-time instead, and so we’ll introduce a small type system to<br />
handle the two syntactic categories of terms that exist. e abstract type of natural numbers and the<br />
type of booleans:<br />
τ ::= Bool<br />
Nat<br />
Which is implemented in <strong>Haskell</strong> as the following datatype:<br />
data Type<br />
= TBool<br />
| TNat<br />
Now for the typing rules:<br />
59