let transform : (module Sounds.T with type t = 'a) -> 'a Sig.consonants option -> 'a Sig.t -> 'a Sig.t = fun (type el) m c init -> let module T = (val m:Sounds.T with type t = el) in let (((v1, v2), _) , _) = init in begin match T.nasal v1, T.nasal v2 with | Some t1, Some t2 -> ( ( (t1, t2) , c ) , None ) | _ -> init end (** The Nasal modifier transform a voyel followed by N and a consonant into a nasal voyel. Does this min that nasal voyel are not a distinct element, but just a merge from two distinct elements ? *) let process : 'a Sig.modifier = fun (type el) m init -> let module T = (val m:Sounds.T with type t = el) in let (((v1, v2), c) , ending) = init in let ending = Option.bind ending (fun x -> x) in let opening = Option.map (fun v -> v.Sig.opening) c in let is_voyel = T.is_voyel v1 && T.is_voyel v2 in match ending, is_voyel, opening with | Some ending, _, _ when T.is_nasal ending -> transform m c init (* Remove the ending consonant, and transform the voyel into the nasal form *) | None, false, Some (opening::tl) when T.is_nasal opening -> (* If there is no voyel here, transform the opening consonant as an ending consonant for the next syllabus *) let c = Option.map (fun c -> { c with Sig.opening = tl ; Sig.ending = (Some (Some opening)) }) c in ( ( (v1, v2) , c ) , None ) | _ -> (* Return the element unchanged *) init