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(num1, num2) = if num1 = Zero orelse num2 = Zero then false else isEqual(pred(num1), pred(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(Zero)) = false | isEven(OnePlus(OnePlus(num))) = isEven(num); fun isEven(Zero) = true | isEven(OnePlus(num)) = not(isEven(num)); fun multiply(num, Zero) = Zero | multiply(Zero, num) = Zero | multiply(num1, OnePlus(Zero)) = num1 | multiply(num1, OnePlus(num2)) = plus(num1, multiply(num1, num2)); fun multiply(num, Zero) = Zero | multiply(num1, OnePlus(num2)) = plus(num1, multiply(num1, 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 lmax = max(left); val rmax = max(right); val lrmax = if lmax < rmax then rmax else lmax in if x < lrmax then lrmax else x 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) = "/";