Merge pull request #68 from gmevel/master

add `CCList.range_by`
This commit is contained in:
Simon Cruanes 2016-04-25 11:46:09 +02:00
commit a722c0c9b8
2 changed files with 33 additions and 0 deletions

View file

@ -792,6 +792,32 @@ module Idx = struct
*) *)
end end
let range_by ~step i j =
let rec range i j acc =
if i=j then i::acc else range i (j-step) (j::acc)
in
if step = 0 then
raise (Invalid_argument "CCList.range_by")
else if (if step > 0 then i>j else i<j) then
[]
else
range i ((j-i)/step*step + i) []
(* note: the last test checks that no error occurs due to overflows. *)
(*$T
range_by ~step:1 0 0 = [0]
range_by ~step:1 5 0 = []
range_by ~step:2 1 0 = []
range_by ~step:2 0 4 = [0;2;4]
range_by ~step:2 0 5 = [0;2;4]
range_by ~step:~-1 0 0 = [0]
range_by ~step:~-1 0 5 = []
range_by ~step:~-2 0 1 = []
range_by ~step:~-2 5 1 = [5;3;1]
range_by ~step:~-2 5 0 = [5;3;1]
range_by ~step:max_int 0 2 = [0]
*)
let range i j = let range i j =
let rec up i j acc = let rec up i j acc =
if i=j then i::acc else up i (j-1) (j::acc) if i=j then i::acc else up i (j-1) (j::acc)

View file

@ -275,6 +275,13 @@ end
(** {2 Other Constructors} *) (** {2 Other Constructors} *)
val range_by : step:int -> int -> int -> int t
(** [range_by ~step i j] iterates on integers from [i] to [j] included,
where the difference between successive elements is [step].
use a negative [step] for a decreasing list.
@raise Invalid_argument if [step=0]
@since NEXT_RELEASE *)
val range : int -> int -> int t val range : int -> int -> int t
(** [range i j] iterates on integers from [i] to [j] included . It works (** [range i j] iterates on integers from [i] to [j] included . It works
both for decreasing and increasing ranges *) both for decreasing and increasing ranges *)