(* "n choose m" -- for nonnegative integers n, m with 0<=m<=n *) (* NOTE: "n choose 0" = 1 for any non-negative n including 0 *) fun choose (n, m) = let exception BadN and BadM in if n <= 0 then raise BadN else if m < 0 orelse m > n then raise BadM else if m = 0 orelse m = n then 1 else choose (n-1, m) + choose (n-1, m-1) end ; (* scanInt (L) converts a list of decimal digits to the integer that is the value of the string in reverse *) fun scanInt (nil) = 0 | scanInt (h::t) = ord(h)-ord(#"0")+10*scanInt(t); (* string2Int (s) converts a string s of decimal digits to its equivalent integer. *) fun string2Int (s) = scanInt (rev(explode(s))); (* The following function prints (onto stdio) the decimal representation of an integer. Note that for negative integers a minus sign is used as opposed to the usual ML convention of using the character "~". *) fun printInt (n) = (* the following iterative function converts a non-negative integer into a list of decimal digits *) let fun prIntIter (n, L) = if n = 0 then if null (L) then [#"0"] else L else prIntIter (n div 10, chr((n mod 10) + ord (#"0"))::L) ; val L = prIntIter (abs(n), []); in if n<0 then print (implode(#"-"::L)) else print(implode (L)) end ; fun comb ([n,m]) = (printInt (choose (string2Int(n), string2Int(m))); print ("\n")); (* SMLofNJ.exportML "combinations"; *) SMLofNJ.exportFn ("combfile", ("comb" ["5", "4"]));