package vocal
Source file ZipperList.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86(**************************************************************************) (* *) (* VOCaL -- A Verified OCaml Library *) (* *) (* Copyright (c) 2018 The VOCaL Project *) (* *) (* This software is free software, distributed under the MIT license *) (* (as described in file LICENSE enclosed). *) (**************************************************************************) type 'a t = { left: 'a list; right: 'a list; len: int; } let empty (_: unit) : 'a t = { left = []; right = []; len = 0 } let is_empty (z: 'a t) : bool = begin match (z.left, z.right) with | ([], []) -> true | _ -> false end let to_list (z: 'a t) : 'a list = List.rev_append (z.left) (z.right) let rec peano_length : 'a . ('a list) -> (int) = fun l -> begin match l with | [] -> 0 | _ :: s -> (peano_length s) + 1 end let make (l: 'a list) : 'a t = { left = []; right = l; len = (peano_length l) } let length (z: 'a t) : int = z.len let move_right (z: 'a t) : 'a t = begin match z.right with | [] -> assert false (* absurd *) | x :: r -> { left = (x :: (z.left)); right = r; len = (z.len) } end let insert_right (x: 'a) (z: 'a t) : 'a t = { left = (z.left); right = (x :: (z.right)); len = ((z.len) + 1) } let remove_right (z: 'a t) : 'a t = begin match z.right with | [] -> assert false (* absurd *) | _ :: r -> { left = (z.left); right = r; len = ((z.len) - 1) } end let move_all_right (z: 'a t) : 'a t = let l = List.rev_append (z.right) (z.left) in { left = l; right = []; len = (z.len) } let move_left (z: 'a t) : 'a t = begin match z.left with | [] -> assert false (* absurd *) | x :: l -> { left = l; right = (x :: (z.right)); len = (z.len) } end let insert_left (x: 'a) (z: 'a t) : 'a t = { left = (x :: (z.left)); right = (z.right); len = ((z.len) + 1) } let remove_left (z: 'a t) : 'a t = begin match z.left with | [] -> assert false (* absurd *) | _ :: r -> { left = r; right = (z.right); len = ((z.len) - 1) } end let move_all_left (z: 'a t) : 'a t = let l = List.rev_append (z.left) (z.right) in make l let is_focused (z: 'a t) : bool = begin match z.right with | [] -> false | _ :: _ -> true end let focused (z: 'a t) : 'a option = begin match z.right with | [] -> None | x :: _ -> Some x end