For example, is there ever a case where a type like type x = A of int * int is better than type y = B of (int * int)? And what does this distinction actually mean?
The places I see that x is worse is trying to match the "argument" of the constructor (seems like it's two arguments, but its printed as one tuple) as a tuple:
type x = A of int * int
type y = B of (int * int)
let v = (1, 1)
(* let a = A v (* Doesn't work *) *)
let b = B v (* Works *)
(* let f = function
| A v -> v (* Doesn't work *) *)
let g = function
| B v -> v (* Works *)
So it looks like it only places restrictions to have multiple arguments, even though they have the same representation?