open Dial module Turner : sig val turn : Dial.t -> int -> Dial.direction -> Dial.t * int (** [turn dial direction] is the new state of the dial after turning [direction] on [dial] *) end = struct (** [turn dial direction] is the new state of the dial after turning [direction] on [dial]. Raises: [dial_out_of_range] if the dial is moved to an invalid state. *) let rec turn dial zero_count direction = let open Dial in match direction with | Left 0 -> (dial, zero_count) | Left n -> let dial' = prev dial in let zero_count' = if Dial.is_zero dial' then zero_count + 1 else zero_count in turn dial' zero_count' (Left (n - 1)) | Right 0 -> (dial, zero_count) | Right n -> let dial' = next dial in let zero_count' = if Dial.is_zero dial' then zero_count + 1 else zero_count in turn dial' zero_count' (Right (n - 1)) end