#lang plait (define-type Exp [numE (n : Number)] [boolE (b : Boolean)] [plusE (left : Exp) (right : Exp)] [timesE (left : Exp) (right : Exp)] [cndE (test : Exp) (then : Exp) (else : Exp)]) (define-type Value [numV (the-number : Number)] [boolV (the-boolean : Boolean)]) (define (num-op op expr1 expr2) (local [(define (unwrap v) (type-case Value v [(numV n) n] [else (error 'num-op "NaN")]))] (numV (op (unwrap expr1) (unwrap expr2))))) (define (boolean-decision v) (type-case Value v [(boolV b) b] [else (error 'if "not a boolean")])) (define (calc e) (type-case Exp e [(numE n) (numV n)] [(boolE b) (boolV b)] [(plusE l r) (num-op + (calc l) (calc r))] [(timesE l r) (num-op * (calc l) (calc r))] [(cndE c t e) (if (boolean-decision (calc c)) (calc t) (calc e))])) (test (calc (plusE (numE 3) (numE 4))) (numV 7)) (test (calc (cndE (boolE #t) (numE 0) (numE 1))) (numV 0))