#+begin_src elisp tangle: no :results none :exports none (setq pwd (file-name-directory buffer-file-name)) (setq name (file-name-nondirectory (substring buffer-file-name 0 -4))) (setq lib (concat pwd "lib/")) (setq testdir (concat pwd "test/")) (setq mli (concat lib name ".mli")) (setq ml (concat lib name ".ml")) (setq test-ml (concat testdir name ".ml")) (org-babel-tangle) #+end_src * Range :PROPERTIES: :header-args: :noweb yes :comments both :END: A range is a sorted list of integers in an interval. - ~"[a-b]"~ : range between a and b (included) - ~"[a]"~ : the list with only one integer a - ~"a"~ : equivalent to "[a]" - ~"[36-53,72-107,126-131]"~ represents the list of integers [ 37 ; 37 ; 38 ; ... ; 52 ; 53 ; 72 ; 73 ; ... ; 106 ; 107 ; 126 ; 127 ; ... ; 130 ; 131 ]. ** Type <<<~Range.t~>>> #+begin_src ocaml :tangle (eval mli) type t #+end_src #+begin_src ocaml :tangle (eval ml) :exports none type t = int list #+end_src ** Conversion #+begin_src ocaml :tangle (eval mli) val of_string : string -> t val to_string : t -> string val to_int_list : t -> int list #+end_src #+begin_src ocaml :tangle (eval ml) :exports none let to_int_list r = r let expand_range r = match String.split_on_char '-' r with | s :: f :: [] -> begin let start = int_of_string s and finish = int_of_string f in assert (start <= finish) ; let rec do_work = function | i when i=finish -> [ i ] | i -> i::(do_work (i+1)) in do_work start end | r :: [] -> [int_of_string r] | [] -> [] | _ -> invalid_arg "Only one range expected" let of_string s = match s.[0] with | '0' .. '9' -> [ int_of_string s ] | _ -> assert (s.[0] = '[') ; assert (s.[(String.length s)-1] = ']') ; let s = String.sub s 1 ((String.length s) - 2) in let l = String.split_on_char ',' s in let l = List.map expand_range l in List.concat l |> List.sort_uniq compare let to_string l = "[" ^ (List.map string_of_int l |> String.concat ",") ^ "]" #+end_src ** Printers #+begin_src ocaml :tangle (eval mli) val pp : Format.formatter -> t -> unit #+end_src #+begin_src ocaml :tangle (eval ml) :exports none let pp ppf t = Format.fprintf ppf "@[%s@]" (to_string t) #+end_src