Simplify this code?

  type t = Step_Count of int;;

  let to_int (Step_Count(n): t) : int =  n;;
  let to_int2 (x: t) : int =
    match x with
    | Step_Count(n) -> n;;

  let to_int3 (x: t) : int = x.0;

to_int and to_int2 compiles. to_int3 does not compile.

What I don’t like about to_int2 is that the match feels like overkill.

What I don’t like about to_int is that the function signature is harder to read

Is something like to_int3 possible? I.e. to ‘index’ into the struct ?


But there is: let to_int = function Step_count n -> n.



If the idea is that the type t is essentially just an integer in disguise, you could use an abstract type:

module Step_count : sig
  type t
  val to_int : t -> int
  (* And any other operations you need *)
end = struct
  type t = int
  let to_int =

Off-topic… To make it even more of an overkill, you can write:

type t = Step_Count of {num_steps: int};;

let to_int (Step_Count{num_steps}: t) : int =  num_steps;;

I like how records-in-variants improve readability.

P.S. This construct of nesting a record inside a variant in a single definition was not part of OCaml from the beginning. Neither was “overloading of record fields” which lets one use the same field name in different record types without annotation overhead, if the compiler knows the type of the record ahead of time. Which is the case for nested records because you always use them with the variant tag.

I’d write let to_int (Setp_count n) = n without annotations, since it’s completely unambiguous what’s happening here to the reader.