(* Subjective self-reports, apart from Evidence: what the trainee said, not what the body did. *) type level = Worse_than_usual | As_usual | Better_than_usual let pp_level ppf = function | Worse_than_usual -> Format.pp_print_string ppf "worse than usual" | As_usual -> Format.pp_print_string ppf "as usual" | Better_than_usual -> Format.pp_print_string ppf "better than usual" type signal = Motivation of level | Difficulty of level type t = { reported_at : Recovery.timestamp; signals : signal list } type error = Duplicate_signal of signal exception Invalid of error let same_category left right = match (left, right) with | Motivation _, Motivation _ | Difficulty _, Difficulty _ -> true | _ -> false let make ~reported_at signals = let rec validate seen = function | [] -> { reported_at; signals } | signal :: rest -> if List.exists (same_category signal) seen then raise (Invalid (Duplicate_signal signal)) else validate (signal :: seen) rest in validate [] signals let reported_at t = t.reported_at let signals t = t.signals