let split_list len l =
  let rec iter accf acc = function
      [] ->
        (
         match acc with
           [] -> List.rev accf
         | _ -> List.rev ((List.rev acc) :: accf)
        )
    | h :: q ->
        if List.length acc >= len then
          iter ((List.rev acc) :: accf) [h] q
        else
          iter accf (h :: acc) q
  in
  iter [] [] l

let rec group_by_2 = function
    [] -> []
  | c1 :: c2 :: q ->
      (c1, c2) :: (group_by_2 q)
  | [_] ->
      failwith "The list must have an even number of elements in list."

let print_list oc string_of_ele l =
  List.iter (fun ele -> Printf.fprintf oc "%s\n" (string_of_ele ele)) l

let rec list_chop n = function
    [] -> []
  | h :: q ->
      if n > 0 then
        h :: (list_chop (n-1) q)
      else
        []

let make_list n ele =
  let rec f acc n =
    if n > 0 then f (ele :: acc) (n-1) else acc
  in
  f [] n

let make_int_list ~low ~high =
  if low > high then
    []
  else
    let rec iter acc = function
        n when n <= high -> iter (n :: acc) (n+1)
      |        _ -> List.rev acc
    in
    iter [] low

let list_diff ?(pred=(=)) l1 l2 =
  List.fold_right
    (fun el acc ->
       if not (List.exists (pred el) l2) then
         el :: acc
       else
         acc
    )
    l1 []

let list_remove_doubles ?(pred=(=)) l =
  List.fold_left
    (fun acc e -> if List.exists (pred e) acc then acc else e :: acc)
    []
    (List.rev l)