Ex.: If define
- fun updatehd newhd (head::tail) = newhd :: tail;then get sharing:
Safe, because list elt's not updatable!
Ex. Obvious recursive def in ML:
- fun fib 0 : int = 1 | fib 1 = 1 | fib n = fib (n-2) + fib (n-1);Iterative solution in Pascal - faster!
Function fastfib (n:integer):integer; val a,b : integer; begin a := 1; b := 1; while n > 0 do begin a := b; b := a + b; n := n-1 (* all done in parallel, else wrong! *) end; fib := a end;
fun fastfib n = let fun fibLoop a b 0 = a | fibLoop a b n : int = fibLoop b (a+b) (n-1) in fibLoop 1 1 n end;
Let's see how you can give a proof of correctness of a functional program:
fun fastfib n : int = let fun fibLoop a b 0 = a | fibLoop a b n : int = fibLoop b (a+b) (n-1) in fibLoop 1 1 n end;Prove fastfib n = fib n where
fun fib 0 = 1 | fib 1 = 1 | fib n = fib (n-2) + fib (n-1);
Let ai = fib i, for all i.
Therefore a0 = a1 = 1, and ai + ai+1 = ai+2 for all i >= 0, by def of fib.
Theorem: For all i, fibLoop ai ai+1 n = ai+n.
Pf by induction on n:
If n = 0, fibLoop ai ai+1 0 = ai = ai+0 by def.
Suppose true for n - 1:
fibLoop ai ai+1 n = fibLoop ai+1 (ai + ai+1) (n - 1) = fibLoop ai+1 ai+2 (n - 1) = ai+1+(n-1) = ai+n.Now
fastfib n = fibLoop 1 1 n = fibLoop a0 a1 n = a0+n = anby the Theorem.
Therefore, for all n, fastfib n = fib n.
Similar proofs can be given for other facts, e.g.,
nlength (append l1 l2) = nlength(l1) + nlength(l2)where
fun nlength  = 0 | nlength (h::rest) = 1 + nlength restand
fun append  l2 = l2 | append (h::rest) l2 = h :: (append rest l2)