In: Computer Science
a splitting function, split_by
Write a splitting function named split_by that takes three arguments
an equality checking function that takes two values and returns a value of type bool,
a list of values that are to be separated,
and a list of separators values.
This function will split the second list into a list of lists. If the checking function indicates that an element of the first list (the second argument) is an element of the second list (the third argument) then that element indicates that the list should be split at that point. Note that this "splitting element" does not appear in any list in the output list of lists.
For example,
split_by (=) [1;2;3;4;5;6;7;8;9;10;11] [3;7] should evaluate to [ [1;2]; [4;5;6]; [8;9;10;11] ] and
split_by (=) [1;2;3;3;3;4;5;6;7;7;7;8;9;10;11] [3;7] should evaluate to [[1; 2]; []; []; [4; 5; 6]; []; []; [8; 9; 10; 11]].
Note the empty lists. These are the list that occur between the 3's and 7's.
split_by (=) ["A"; "B"; "C"; "D"] ["E"] should evaluate to [["A"; "B"; "C"; "D"]]
Annotate your function with types.
Also add a comment explaining the behavior of your function and its type. Try to write this function so that the type is as general as possible.
OCaml code without using rec keyword in it.
Given question, we need to write split_by function in ocaml, taking three arguments, below is snipet code with detail implementation of accoriding to given points in question. Three arguments include first equality operator, second list and thirst splitting element, below is solution snippet with detailed explaination and tested split_by function with sample output given in question.
Solution snippet:
(* is_elem_by function returns true if list right fold matching with element_list *)
(* we will use this in split_by for checking seperator with x value *)
let is_elem_by (funcBool:'a -> 'b -> bool) (element_list:'b) (forlist:'a list): bool =
List.fold_right (fun x y -> if (funcBool x element_list) then true else y) forlist false
(* As stated in question, split_by function taking three arguments *)
let split_by (funcBool:'a -> 'b -> bool) (forcompletelist:'b list) (seperator:'a list): 'b list list =
(* check if given x y elements match in function *)
let funcBool x y =
if (is_elem_by funcBool x seperator)
(* for matching element with seperator *)
then []::y
(* return list else match tail *)
else match y with
| hd::tail -> (x::hd)::tail
| [] -> [] in
(* returns final list after evaluating matching element *)
List.fold_right funcBool forcompletelist [[]]
Code screenshot if having problem with indentation in snippet code.
Output: test out split_by function:
Test for empty list: