// What dynamic dispatch can't do... open System;; type number = Integer of int | Rational of int*int | Real of float | Complex of float*float;; // addition of any two numbers let rec add = function | (Integer(a),Integer(b)) -> Integer(a+b) | (Integer(a), Rational(n,d)) -> Rational(a*d+n,d) | (Integer(a), Real(b)) -> Real(float(a)+b) | (Integer(a), Complex(r,i)) -> Complex(float(a)+r,i) | (Rational(a,b),Rational(c,d)) ->Rational(a*d+c*b,b*d) | (Rational(a,b),Real(r)) -> Real(float(a)/float(b)+r) | (Rational(a,b),Complex(r,i))->Complex(float(a)/float(b)+r,i) | (Real(a),Real(b)) -> Real(a+b) | (Real(a),Complex(r,i)) -> Complex(a+r,i) | (Complex(a,b),Complex(c,d)) -> Complex(a+c,b+d) | (x,y) -> add(y,x);; // equality between any two numbers let rec numeq = function | (Integer(a),Integer(b)) -> a=b | (Integer(a), Rational(n,d)) -> a*d=n | (Integer(a), Real(b)) -> float(a)=b | (Integer(a), Complex(r,0.0)) -> float(a)=r | (Rational(a,b),Rational(c,d)) -> a*d = c*b | (Rational(a,b),Real(r)) ->float(a)/float(b) = r | (Rational(a,b),Complex(r,0.0))-> float(a)/float(b)=r | (Real(a),Real(b)) -> a=b | (Real(a),Complex(r,0.0)) -> a=r | (Complex(a,b),Complex(c,d)) -> a=c && b=d | (_,Complex(r,_)) -> false | (x,y) -> numeq(y,x);; // string form let tostring = function | Integer(n) -> string(n) | Rational(a,b) -> string(a)+"/"+string(b) | Real(a) -> string(a) | Complex(r,i) -> string(r)+"+"+string(i)+"i";; let somenums = [Real(3.14);Rational(3,4);Complex(0.1,2.0);Integer(2);Complex(2.0,0.0);Rational(1,2)];; let sum(Ns:number list) = // sum of all numbers in a number list let mutable i = 0 let mutable ax = Integer(0) // accumulator while i ax | (car::cdr) -> sum (add(ax,car)) cdr sum (Integer(0)) Ns;; let thesum = sum(somenums); Console.WriteLine( thesum ); printf "%s\n" (tostring(thesum));;