(* edits.ml *)
type 'a edit = Transpose of int
| Insert of int * 'a
| Append of 'a
| Delete of int
exception Error
let transpose n xs =
let rec trans(n, ys, xs) =
match xs with
[] -> raise Error
| [_] -> raise Error
| x1 :: (x2 :: xs as x2_xs) ->
if n = 0
then List.rev_append ys (x2 :: x1 :: xs)
else trans(n - 1, x1 :: ys, x2_xs)
in if n < 0 then raise Error else trans(n, [], xs)
let insert (n, z) xs =
let rec ins(n, ys, xs) =
match xs with
[] -> raise Error
| x :: xs as x_xs ->
if n = 0
then List.rev_append ys (z :: x_xs)
else ins(n - 1, x :: ys, xs)
in if n < 0 then raise Error else ins(n, [], xs)
let append y xs = xs @ [y]
let delete n xs =
let rec del(n, ys, xs) =
match xs with
[] -> raise Error
| x :: xs ->
if n = 0
then List.rev_append ys xs
else del(n - 1, x :: ys, xs)
in if n < 0 then raise Error else del(n, [], xs)
let doEdit(edit, xs) =
match edit with
Transpose n -> transpose n xs
| Insert(n, z) -> insert (n, z) xs
| Append y -> append y xs
| Delete n -> delete n xs
let rec doEdits(edits, xs) =
match edits with
[] -> xs
| edit :: edits -> doEdits(edits, doEdit(edit, xs))