97
97
end
98
98
99
99
module Workout = struct
100
-
Removed:
type error = Empty_workout
100
+
Added:
type error =
101
+
Added:
| Empty_workout
102
+
Added:
| Excess_sets_per_muscle of { muscle : Exercise.Muscle.t; sets : int }
103
+
Added:
101
104
type t = { name : string; stimuli : Stimulus.t list }
102
105
103
106
exception Invalid of error
104
107
108
+
Added:
(* HD1, The Science of Bodybuilding: "one set per exercise, and at the most,
109
+
Added:
three sets per muscle, is all that is required." *)
110
+
Added:
let sets_per_muscle_ceiling = 3
111
+
Added:
112
+
Added:
let pp_error ppf = function
113
+
Added:
| Empty_workout ->
114
+
Added:
Format.pp_print_string ppf "a workout must prescribe at least one set"
115
+
Added:
| Excess_sets_per_muscle { muscle; sets } ->
116
+
Added:
Format.fprintf ppf "%a receives %d sets, over the ceiling of %d"
117
+
Added:
Exercise.Muscle.pp muscle sets sets_per_muscle_ceiling
118
+
Added:
119
+
Added:
(* Each delivery exercise counts one set toward its primary muscle;
120
+
Added:
substitutes are alternatives, not added volume. Returns the first muscle
121
+
Added:
over the ceiling, if any. *)
122
+
Added:
let over_ceiling stimuli =
123
+
Added:
let primaries =
124
+
Added:
List.concat_map Stimulus.exercises stimuli
125
+
Added:
|> List.map Exercise.primary_muscle
126
+
Added:
in
127
+
Added:
let sets muscle =
128
+
Added:
List.length (List.filter (Exercise.Muscle.equal muscle) primaries)
129
+
Added:
in
130
+
Added:
List.find_map
131
+
Added:
(fun muscle ->
132
+
Added:
let n = sets muscle in
133
+
Added:
if n > sets_per_muscle_ceiling then Some (muscle, n) else None)
134
+
Added:
primaries
135
+
Added:
105
136
let make ~name ~stimuli =
106
137
match stimuli with
107
138
| [] -> raise (Invalid Empty_workout)
108
-
Removed:
| _ -> { name; stimuli }
139
+
Added:
| _ -> (
140
+
Added:
match over_ceiling stimuli with
141
+
Added:
| Some (muscle, sets) ->
142
+
Added:
raise (Invalid (Excess_sets_per_muscle { muscle; sets }))
143
+
Added:
| None -> { name; stimuli })
109
144
110
145
let name t = t.name
111
146
let stimuli t = t.stimuli