fun factorial(0) = 1 | factorial(n) = n * factorial(n-1); fun multiply(a, 0) = 0 | multiply(a, b) = a + multiply(a, b-1); fun gcd(a, 0) = a | gcd(a, b) = gcd(b, a mod b); datatype rational = Fraction of int * int; fun add(Fraction(a, b), Fraction(c, d)) = let val numerator = a * d + c * b; val denominator = b * d; val divisor = gcd(numerator, denominator); in Fraction(numerator div divisor, denominator div divisor) end; datatype wholeNumber = Zero | OnePlus of wholeNumber; val five = OnePlus(OnePlus(OnePlus(OnePlus(OnePlus(Zero))))); val six = OnePlus(five); fun succ(num) = OnePlus(num); fun asWholeNumber(0) = Zero | asWholeNumber(n) = OnePlus(asWholeNumber(n-1)); fun pred(OnePlus(num)) = num; fun plus(num, Zero) = num | plus(num1, OnePlus(num2)) = plus(OnePlus(num1), num2); fun isLessThanOrEq(Zero, num) = true | isLessThanOrEq(num, Zero) = false | isLessThanOrEq(OnePlus(num1), OnePlus(num2)) = isLessThanOrEq(num1, num2); (* isLessThan *) fun isLessThan(num, Zero) = false | isLessThan(Zero, num) = true | isLessThan(OnePlus(num1), OnePlus(num2)) = isLessThan(num1, num2); (* isEqual *) fun isEqual(Zero, Zero) = true | isEqual(Zero, num) = false | isEqual(num, Zero) = false | isEqual(OnePlus(num1), OnePlus(num2)) = isEqual(num1, num2); fun minus(num, Zero) = num | minus(OnePlus(num1), OnePlus(num2)) = minus(num1, num2); fun asInt(Zero) = 0 | asInt(OnePlus(num)) = 1 + asInt(num); (* ex 6.1.(1 & 2) *) fun isEven(Zero) = true | isEven(OnePlus(num)) = not isEven(num); fun multiply(num, Zero) = | multiply(Zero, num) = | multiply(num1, OnePlus(Zero)) = | multiply(num1, OnePlus(num2)) = datatype tree = Leaf of int | Internal of (int * tree * tree); val t = Internal(5, Internal(2, Leaf(1), Leaf(8)), Internal(6, Leaf(2), Internal(7, Leaf(3), Leaf(1)))); fun treeSum(Leaf(x)) = x | treeSum(Internal(x, left, right)) = x + treeSum(left) + treeSum(right); fun printTree(Leaf(x)) = Int.toString(x) | printTree(Internal(x, left, right)) = "(" ^ Int.toString(x) ^ ": " ^ printTree(left) ^ ", " ^ printTree(right) ^ ")"; (* exercises from 6.2 ... *) fun nodes(Leaf(x)) = 1 | nodes(Internal(x, left, right)) = 1 + nodes(left) + nodes(right); fun leaves(Leaf(x)) = 1 | leaves(Internal(x, left, right)) = leaves(left) + leaves(right); fun internals(Leaf(x)) = 0 | internals(Internal(x, left, right)) = 1 + internals(left) + internals(right); fun contains(y, Leaf(x)) = x = y | contains(y, Internal(x, left, right)) = x = y orelse contains(y, left) orelse contains(y, right); fun max(Leaf(x)) = x | max(Internal(x, left, right)) = let val leftMax = max(left); val rightMax = max(right); in if x > leftMax andalso x > rightMax then x else if leftMax > rightMax then leftMax else rightMax end; (* For Exercises 6.2.(6-8) *) datatype tree = Leaf of int | Internal of (int * tree * tree); (* For Exercises 6.2.(14-17) *) datatype operation = Plus | Minus | Mul | Div; datatype expression = Internal of operation * expression * expression | Leaf of int; fun printOper(Plus) = "+" | printOper(Minus) = "-" | printOper(Mul) = "*" | printOper(Div) = "/";