package plato

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file slice.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
[@@@warning "@A"]

type ('elt, 'list) concat =
  | ConcatLeft of ('elt -> 'list -> 'list)
  | ConcatRight of ('list -> 'elt -> 'list)
  | Set of (int -> 'elt -> 'list -> unit)

let slice (type a b c)
    ?(start: int option) ?(stop: int option) ?(step: int = 1)
    ?(sub: (a -> int -> int -> a) option) (length: a -> int) (get: a -> int -> b)
    (concat: (b, c) concat) (empty: int -> c) (post: c -> a) (s: a) : a =
  let l = length s in
  let start =
    match start with
    | None ->
      if step < 0 then
        l - 1
      else
        0
    | Some start when start >= 0 -> min start l
    | Some start -> max 0 (l + start)
  in
  let stop =
    match stop with
    | None ->
      if step > 0 then
        l
      else
        ~-1
    | Some stop when stop >= 0 -> min stop l
    | Some stop -> max 0 (stop + l)
  in
  match sub, step with
  | Some sub, 1 -> sub s start (stop - start)
  | _, _ ->
    let l : int list ref = ref [] in
    let i : int ref = ref start in
    let len : int ref = ref 0 in
    let () =
      if step > 0 then
        while !i < stop do
          l := !i :: !l;
          i := !i + step;
          incr len
        done
      else
        while !i > stop do
          l := !i :: !l;
          i := !i + step;
          incr len
        done
    in
    let res =
      match concat with
      | ConcatLeft concat ->
        List.fold_left
          (fun acc i -> concat (get s i) acc)
          (empty !len)
          !l
      | ConcatRight concat ->
        List.fold_right
          (fun i acc -> concat acc (get s i))
          !l
          (empty !len)
      | Set set ->
        let res = empty !len in
        List.iteri
          (fun it idx -> set (!len - it - 1) (get s idx) res)
          !l;
        res
    in
    post res
OCaml

Innovation. Community. Security.