(* Have: add : int -> int -> int Want: add' : int -> -> *) fun add 0 y = y | add n y = 1 + (add (n-1) y); fun add' 0 y = y | add' n y = < 1 + ~(add' (n-1) y)>; (* Have: mult : int -> int -> int Want: mult' : int -> int> *) fun mult 0 y = 0 | mult n y = y + (mult (n-1) y); fun mult' 0 = 0> | mult' n = y + ~(mult' (n-1)) y>; (* Have: member : ['a=].'a list -> 'a -> bool Want: member' : 'a list -> <'a> -> *) fun member [] x = false | member (y::ys) x = if x=y then true else member ys x; fun member' [] x = | member' (y::ys) x = ; fun member' [] x = | member' [y] x = <~x = ~(lift y)> | member' (y::ys) x = ; (* Have: dotprod : int -> int list -> int list -> int Want: dotprod' int -> int list> *) fun dotprod 0 xs ys = 0 | dotprod n (x::xs) (y::ys) = (x * y) + (dotprod (n-1) xs ys) fun nth 0 (x::xs) = x | nth n (x::xs) = nth (n-1) xs; (* use a helper function and the nth function *) fun help 0 next xs = 0> | help n next (x::xs) = ( ~(lift x) * (nth ~(lift next) ys) ) + ~(help (n-1) (next+1) xs) ys>; fun dotprod' n xs = help n 0 xs; (* Use pattern matching, but code looks ugly since safe-beta doesn't apply *) fun dotprod' 0 xs = 0> | dotprod' n (x::xs) = ( ~(lift x) * y ) + ~(dotprod' (n-1) xs) ys>; (* Stage the multiplication *) fun mult 0 x = <0> | mult 1 x = x | mult y x = < ~(lift y) * ~x >; (* This applies the optimization rules *) fun help 0 next xs = 0> | help 1 next [x] = ~(mult x )> | help n next (x::xs) = ~(mult x ) + ~(help (n-1) (next+1) xs) ys>; fun dotprod' n xs = help n 0 xs; (* Finally an analyis version of the addition function *) fun add <0> x = x | add n x = < ~n + ~x >; (* for the ultimate dot-product *) fun help 0 next xs = 0> | help 1 next [x] = ~(mult x )> | help n next (x::xs) = ~(add (mult x ) <~ (help (n-1) (next+1) xs) ys> )>; fun dotprod' n xs = help n 0 xs; (* Transformers VS generators *) fun add2 n = ~(add' n )>; (* Compare two versions *) fun add3 0 y = y | add3 n y = < 1 + ~(add3 (n-1) y)>; fun add4 0 = y> | add4 n = 1 + ~(add4 (n-1)) y>;