(*Generated by Lem from list_extra.lem.*)


open Lem_bool
open Lem_maybe
open Lem_basic_classes
open Lem_tuple
open Lem_num
open Lem_list
open Lem_assert_extra

(* ------------------------- *)
(* head of non-empty list    *)
(* ------------------------- *)
(*val head : forall 'a. list 'a -> 'a*)
(*let head l = match l with | x::xs -> x | [] -> failwith "List_extra.head of empty list" end*)


(* ------------------------- *)
(* tail of non-empty list    *)
(* ------------------------- *)
(*val tail : forall 'a. list 'a -> list 'a*)
(*let tail l = match l with | x::xs -> xs | [] -> failwith "List_extra.tail of empty list" end*)


(* ------------------------- *)
(* last                      *)
(* ------------------------- *)
(*val last : forall 'a. list 'a -> 'a*)
let rec last l = ((match l with | [x] -> x | x1::x2::xs -> last (x2 :: xs) | [] -> failwith "List_extra.last of empty list" ))


(* ------------------------- *)
(* init                      *)
(* ------------------------- *)

(* All elements of a non-empty list except the last one. *)
(*val init : forall 'a. list 'a -> list 'a*)
let rec init l = ((match l with | [x] -> [] | x1::x2::xs -> x1::(init (x2::xs)) | [] -> failwith "List_extra.init of empty list" ))


(* ------------------------- *)
(* foldl1 / foldr1           *)
(* ------------------------- *)

(* folding functions for non-empty lists,
    which don`t take the base case *)
(*val foldl1 : forall 'a. ('a -> 'a -> 'a) -> list 'a -> 'a*)
let foldl1 f x_xs = ((match x_xs with | (x :: xs) -> List.fold_left f x xs | [] -> failwith "List_extra.foldl1 of empty list" ))

(*val foldr1 : forall 'a. ('a -> 'a -> 'a) -> list 'a -> 'a*)
let foldr1 f x_xs = ((match x_xs with | (x :: xs) -> List.fold_right f xs x | [] -> failwith "List_extra.foldr1 of empty list" ))

  
(* ------------------------- *)
(* nth element               *)
(* ------------------------- *)

(* get the nth element of a list *)
(*val nth : forall 'a. list 'a -> nat -> 'a*)
(*let nth l n = match index l n with Just e -> e | Nothing -> failwith "List_extra.nth" end*)


(* ------------------------- *)
(* Find_non_pure             *)
(* ------------------------- *)
(*val findNonPure : forall 'a. ('a -> bool) -> list 'a -> 'a*) 
let findNonPure p0 l = ((match (list_find_opt p0 l) with 
  | Some e      -> e
  | None     -> failwith "List_extra.findNonPure"
))


(* ------------------------- *)
(* zip same length           *)
(* ------------------------- *)

(*val zipSameLength : forall 'a 'b. list 'a -> list 'b -> list ('a * 'b)*) 
(*let rec zipSameLength l1 l2 = match (l1, l2) with
  | (x :: xs, y :: ys) -> (x, y) :: zipSameLength xs ys
  | ([], []) -> []
  | _ -> failwith "List_extra.zipSameLength of different length lists"

end*)

