1
-
Removed:
(** Core measurement types for hito.
1
+
Added:
(** Physical quantities recorded during training.
2
2
3
-
Removed:
These types model the physical quantities recorded during training: the load
4
-
Removed:
on the bar ({!Weight}), the number of repetitions performed ({!Reps}), and a
5
-
Removed:
prescribed target repetition band ({!Rep_range}, e.g. Mentzer's 6-8).
3
+
Added:
Every type here is abstract and constructible only through a smart
4
+
Added:
constructor, so an invalid measurement cannot exist. *)
6
5
7
-
Removed:
Every type in this module is [abstract]: values can only be created through
8
-
Removed:
smart constructors that reject nonsensical inputs (negative loads, zero or
9
-
Removed:
negative reps, inverted ranges). Once you hold a value of one of these
10
-
Removed:
types, it is guaranteed to be valid — illegal measurements are
11
-
Removed:
unrepresentable.
12
-
Removed:
13
-
Removed:
This module is part of the pure domain core: it has no dependency on any web
14
-
Removed:
framework, database, or serialization library. *)
15
-
Removed:
16
-
Removed:
(** A validation error explaining why a smart constructor rejected its input.
17
-
Removed:
Rendered for developers and, where appropriate, surfaced to users. *)
18
6
type error =
19
-
Removed:
| Negative of string (** A quantity that must be >= 0 was negative. *)
20
-
Removed:
| Not_positive of string (** A quantity that must be > 0 was <= 0. *)
21
-
Removed:
| Inverted_range of string
22
-
Removed:
(** A range whose lower bound exceeded its upper bound. *)
7
+
Added:
| Negative (** A quantity that must be >= 0 was negative, or not finite. *)
8
+
Added:
| Not_positive (** A quantity that must be > 0 was <= 0. *)
9
+
Added:
| Inverted_range (** A range's lower bound exceeded its upper bound. *)
23
10
24
11
val pp_error : Format.formatter -> error -> unit
25
-
Removed:
(** [pp_error fmt e] pretty-prints a human-readable description of [e]. *)
26
12
27
-
Removed:
(** Barbell / dumbbell load, stored internally in kilograms.
28
-
Removed:
29
-
Removed:
Weight is a nonnegative quantity: a body-weight movement may legitimately
30
-
Removed:
carry a load of [0.0], but a negative load is never valid. *)
13
+
Added:
(** Load in kilograms. Nonnegative: body-weight movements are [zero]. *)
31
14
module Weight : sig
32
15
type t
33
-
Removed:
(** An abstract, always-valid weight. *)
34
16
35
17
val of_kg : float -> (t, error) result
36
-
Removed:
(** [of_kg kg] is [Ok w] when [kg] is finite and [>= 0.0], otherwise
37
-
Removed:
[Error (Negative _)]. *)
38
-
Removed:
39
18
val to_kg : t -> float
40
-
Removed:
(** [to_kg w] is the load of [w] expressed in kilograms. *)
41
-
Removed:
42
19
val zero : t
43
-
Removed:
(** [zero] is a load of [0.0] kg, for body-weight movements. *)
44
-
Removed:
45
20
val compare : t -> t -> int
46
-
Removed:
(** Total ordering by kilograms. *)
47
-
Removed:
48
21
val equal : t -> t -> bool
49
-
Removed:
(** [equal a b] is [true] when [a] and [b] denote the same load. *)
50
-
Removed:
51
22
val pp : Format.formatter -> t -> unit
52
-
Removed:
(** Pretty-prints a weight, e.g. ["60.0 kg"]. *)
53
23
end
54
24
55
-
Removed:
(** A count of completed repetitions.
56
-
Removed:
57
-
Removed:
Reps are a strictly positive whole number: a logged set has at least one
58
-
Removed:
rep. (An abandoned attempt is modelled elsewhere, not as zero reps.) *)
25
+
Added:
(** A completed repetition count. Strictly positive. *)
59
26
module Reps : sig
60
27
type t
61
-
Removed:
(** An abstract, always-valid repetition count. *)
62
28
63
29
val of_int : int -> (t, error) result
64
-
Removed:
(** [of_int n] is [Ok r] when [n > 0], otherwise [Error (Not_positive _)]. *)
65
-
Removed:
66
30
val to_int : t -> int
67
-
Removed:
(** [to_int r] is the underlying repetition count. *)
68
-
Removed:
69
31
val compare : t -> t -> int
70
-
Removed:
(** Total ordering by count. *)
71
-
Removed:
72
32
val equal : t -> t -> bool
73
-
Removed:
(** [equal a b] is [true] when [a] and [b] denote the same count. *)
74
-
Removed:
75
33
val pp : Format.formatter -> t -> unit
76
-
Removed:
(** Pretty-prints a rep count, e.g. ["8 reps"]. *)
77
34
end
78
35
79
-
Removed:
(** An inclusive target repetition band, such as Mentzer's canonical 6-8.
80
-
Removed:
81
-
Removed:
A range is valid when its lower bound is [<=] its upper bound; both bounds
82
-
Removed:
are themselves valid {!Reps.t} values (hence strictly positive). *)
36
+
Added:
(** An inclusive target rep band, such as Mentzer's canonical 6-8. *)
83
37
module Rep_range : sig
84
38
type t
85
-
Removed:
(** An abstract, always-valid inclusive rep range. *)
86
39
87
40
val make : min:Reps.t -> max:Reps.t -> (t, error) result
88
-
Removed:
(** [make ~min ~max] is [Ok range] when [min <= max], otherwise
89
-
Removed:
[Error (Inverted_range _)]. *)
90
-
Removed:
91
41
val min : t -> Reps.t
92
-
Removed:
(** The inclusive lower bound. *)
93
-
Removed:
94
42
val max : t -> Reps.t
95
-
Removed:
(** The inclusive upper bound. *)
96
-
Removed:
97
43
val contains : t -> Reps.t -> bool
98
-
Removed:
(** [contains range r] is [true] when [r] falls within [range] inclusive. *)
99
-
Removed:
100
44
val equal : t -> t -> bool
101
-
Removed:
(** [equal a b] is [true] when [a] and [b] have equal bounds. *)
102
-
Removed:
103
45
val pp : Format.formatter -> t -> unit
104
-
Removed:
(** Pretty-prints a range, e.g. ["6-8 reps"]. *)
105
46
end