Aufgabe 1 Exp = { toString : Unit -> String, isValue : Unit -> Bool, value : Unit -> int, step : Unit -> Exp, steps : Unit -> Exp } expClass : (Unit -> Exp) -> Exp expClass = \self : Unit -> Exp. { toString = \_:Unit. "abstract Exp", isValue = \_:Unit. false, value = \_:Unit. 0, step = \_:Unit. self(), steps = \_:Unit. let this = self() in if this.isValue() then this else (this.step()).steps() } newExp : Unit -> Exp newExp = fix self: Unit -> Exp. \_:Unit. expClass self cIntClass : Int -> (Unit -> Exp) -> Exp cIntClass = \i:Int. \self: Unit -> Exp. let super = expClass self in { toString = \_:Unit. Integer.toString(i), isValue = \_:Unit. true, value = \_:Unit. i, step = super.step, steps = super.steps } newCInt : Int -> Exp newCInt = \i:Int. (fix self: Unit->Exp. \_:Unit. cIntClass i self) () plusClass : Exp -> Exp -> (Unit -> Exp) -> Exp plusClass = \t1:Exp. \t2:Exp. \self: Unit -> Exp. let super = expClass self in { toString = \_:Unit. "(" + t1.toString() + " + " + t2.toString() + ")", isValue = super.isValue, value = super.value, step = if t1.isValue() then if t2.isValue() then newCInt (t1.value() + t2.value()) else newPlus (t1, t2.step()) else newPlus (t1.step(), t2), steps = super.steps } newPlus : Exp -> Exp -> Exp newPlus = \t1:Exp. \t2:Exp. (fix self: Unit->Exp. \_:Unit. plusClass t1 t2 self) () Aufgabe 2 Object = { id : Int } objectClass = Unit -> Object objectClass = let objectCounter = ref -1 in \_: Unit. (objectCounter := !objectCounter + 1; { id = !objectCounter }) A = { id : Int, bla : Unit -> String } aClass = \_:Unit. let super = objectClass () in { id = super.id, bla = \_:Unit. "hallo" }