open StdLabels type t = | Lenght of int | Contain of char * int option | NotContain of char * int option (** Return true if the word match the given filter *) let check_filter : string -> t -> bool = fun word f -> match f with | Lenght l -> l = String.length word | Contain (c, pos) -> ( match pos with | None -> String.contains word c | Some i -> Char.equal c (String.get word i) ) | NotContain (c, pos) -> ( match pos with | None -> not (String.contains word c) | Some i -> not (Char.equal c (String.get word i)) ) let is_valid : t -> t -> bool = fun t1 t2 -> match (t1, t2) with | Lenght _, Lenght _ -> false | Contain (c1, _), NotContain (c2, None) -> not (Char.equal c1 c2) | NotContain (c1, None), Contain (c2, _) -> not (Char.equal c1 c2) | Contain (c1, Some i1), Contain (c2, Some i2) -> Char.equal c1 c2 || i1 <> i2 | _ -> true (** Add a new filter in the list if it is compatible with the existing ones *) let add : t -> t list -> t list = fun t filters -> match List.for_all ~f:(is_valid t) filters with | true -> t :: filters | false -> filters let merge_lists : init:t list -> t list -> t list = fun ~init news -> List.fold_left ~f:(fun acc t -> add t acc) ~init news