/// Skip first n elements of the given nested list, preserving the nesting structure let rec skipNested n list = match list with | _ when n <= 0 -> list | []::xss -> skipNested n xss | [_]::xss -> skipNested (n-1) xss | (_::xs)::xss -> skipNested (n-1) (xs::xss) | [] -> failwith "skipNested: insufficient number of elements" /// Take the first n elements, preserving the nesting structure let rec takeNested n list = let rec loop accg accr n list = let addg g = match g with [] -> accr | _ -> (List.rev g)::accr match list with | _ when n <= 0 -> List.rev (addg accg) | []::xss -> loop accg accr n xss | [x]::xss -> loop [] (addg (x::accg)) (n-1) xss | (x::xs)::xss -> loop (x::accg) accr (n-1) (xs::xss) | [] -> failwith "takeNested: insufficient number of elements" loop [] [] n list /// Keep taking elements while 'f' holds, preserving the nesting structure let rec takeWhileNested f list = let rec loop accg accr list = let addg g = match g with [] -> accr | _ -> (List.rev g)::accr match list with | (x::_)::_ when not (f x) -> List.rev (addg accg) | [] -> List.rev (addg accg) | []::xss -> loop accg accr xss | [x]::xss -> loop [] (addg (x::accg)) xss | (x::xs)::xss -> loop (x::accg) accr (xs::xss) loop [] [] list /// Truncate nested list to a given length, preserving the structure let rec truncateNested n list = let rec loop accg accr n list = let addg g = match g with [] -> accr | _ -> (List.rev g)::accr match list with | _ when n <= 0 -> List.rev (addg accg) | []::xss -> loop accg accr n xss | [x]::xss -> loop [] (addg (x::accg)) (n-1) xss | (x::xs)::xss -> loop (x::accg) accr (n-1) (xs::xss) | [] -> List.rev (addg accg) loop [] [] n list /// Take a slice from start to finish, preserving the strucutre let sliceNested start finish list = list |> skipNested start |> takeNested (finish - start + 1) let sharedPrefixNested l1 l2 = let rec loop accg accr l1 l2 = let addg g = match g with [] -> accr | _ -> (List.rev g)::accr match l1, l2 with | []::xss, []::yss -> loop accg accr xss yss | [x]::xss, [y]::yss when x = y -> loop [] (addg (x::accg)) xss yss | (x::xs)::xss, (y::ys)::yss when x = y -> loop (x::accg) accr (xs::xss) (ys::yss) | _ -> List.rev (addg accg), (l1, l2) loop [] [] l1 l2 /// Collect all elements, adding newly generated items to nesting groups let collectNested f list = let rec appendRev acc xs = match xs with x::xs -> appendRev (x::acc) xs | [] -> acc let rec loop accg accr list = let addg g = match g with [] -> accr | _ -> (List.rev g)::accr match list with | [] -> List.rev (addg accg) | []::xss -> loop accg accr xss | [x]::xss -> loop [] (addg (appendRev accg (f x))) xss | (x::xs)::xss -> loop (appendRev accg (f x)) accr (xs::xss) loop [] [] list /// Map for nested lists let mapNested f l = List.map (List.map f) l /// Fold for nested lists let foldNested f st l = List.fold f st (List.concat l) /// Add index to elements of a nested list let indexedNested l = [ let mutable n = -1 for g in l -> [ for v in g do n <- n + 1; yield n, v ] ] /// Reverse for nested lists let revNested l = List.rev (List.map List.rev l)