open StdLabels module M(T:Sounds.T) = struct type voyel = T.t Modifiers.Sig.voyel type group = voyel * T.t Modifiers.Sig.consonants option type modifier = T.t Modifiers.Sig.modifier (** Apply all the modifiers to the syllabic group in order to correct the relation between the elements This is just a fold_left list, and the order matter : for example nasalisation shall be applied after the S vocalisation *) let apply_modifiers : group * T.t option option -> modifier list -> group * T.t option option = fun e m -> List.fold_left m ~init:e ~f:(fun e f -> f (module T:Sounds.T with type t = T.t) e) let change_voyel = fun init -> let (((v1, v2), _) , ending) = init in match ending with | None -> v2 | Some _ -> v1 let rec _rebuild ~(m:modifier list) acc ending_consonant : group list -> T.t list = function | [] -> acc | hd::tl -> let modifier = (Modifiers.vocalize_s) :: (Modifiers.nasal) :: m in let (voyel, consonants), ending_consonant = apply_modifiers (hd, ending_consonant) modifier in let voyel = change_voyel ((voyel, consonants), ending_consonant) in (* Add the last consonant and the voyel *) let acc = match ending_consonant with | None -> voyel::acc | Some s -> let default = voyel :: acc in match s with | None -> default | Some s -> voyel :: s::acc in match consonants with | None -> _rebuild ~m:[] acc None tl | Some {ending; opening; following} -> let acc = match following with | None -> acc | Some s -> s::acc in match opening with | [] ->_rebuild ~m:[] acc ending tl | opening -> _rebuild ~m:[] (opening @ acc) ending tl (** Rebuild the list in the normal order The voyels have to be choosen, depending either they are followed by a consonant or not Some consonants may be changed depending of the following voyel The list has to be reversed and so one *) let rebuild : T.t Modifiers.Sig.consonants option -> group list -> T.t list = fun ending elems -> let elems' = match ending with | None -> elems | Some _ -> ((T.none, T.none), ending)::elems in _rebuild ~m:[Modifiers.mute_consonant] [] None elems' end