let rec rev1 l =
match l with
| [] -> []
| hd::tl -> List.rev tl @ [hd]
let rec rev2 l k =
match l with
| [] -> k []
| hd::tl -> rev2 tl (fun tl' -> k (tl' @ [hd]))
let rev2_top l = rev2 l (fun x -> x)
let () =
assert (rev1 [1;2;3] = [3;2;1]) ;
assert (rev2_top [1;2;3] = [3;2;1])
type 'a k =
| Id
| Append of 'a k * 'a
let rec apply k x =
match k with
| Id -> x
| Append (k,hd) -> apply k (x@[hd])
let rec rev3 l k =
match l with
| [] -> apply k []
| hd::tl -> rev3 tl (Append (k,hd))
let rev3_top l = rev3 l Id
let () =
assert (rev3_top [1;2;3] = [3;2;1])
let rec rev4 l k =
match l with
| [] -> k
| hd::tl -> rev4 tl (hd::k)
let rev4_top l = rev4 l []
let () =
assert (rev4_top [1;2;3] = [3;2;1])
let rec irev_while l =
let l = ref l in
let r = ref [] in
while !l <> [] do
r := List.hd !l :: !r ;
l := List.tl !l
done ;
!r
let rec irev l =
let l = ref l in
let r = ref [] in
let rec w () =
if !l <> [] then begin
r := List.hd !l :: !r ;
l := List.tl !l ;
w ()
end
in
w () ;
!r
let rec irev' l =
let s : 'a list * 'a list = (l,[]) in
let rec w s =
let l = fst s in
if l <> [] then
let l = fst s in
let r = snd s in
let v = List.hd l :: r in
let s = (fst s, v) in
let l = fst s in
let v = List.tl l in
let s = (v, snd s) in
w s
else
s
in
let s = w s in
snd s
let () =
assert (irev_while [1;2;3] = [3;2;1]) ;
assert (irev [1;2;3] = [3;2;1]) ;
assert (irev' [1;2;3] = [3;2;1])