Ocaml can of course do some type inference, but awkwardly often I have to annotate argument types, and I wonder if there’s some coding practice that would cut down on this.
type wit = { weight: int; index: int }
type lit = { length: int; index: int }
type lwt = A of wit | B of lit
let show_wit a = Printf.sprintf "index %d, %dg" a.index a.weight
let show_lit a = Printf.sprintf "index %d, %dcm" a.index a.length
let show_lwt p = match p with
| A a -> show_wit a
| B a -> show_lit a
;;
print_endline (show_lwt (B {index = 1; length = 10}))
… And ocaml says about that:
| let show_wit a = Printf.sprintf "index %d, %dg" a.index a.weight
^^^^^^
Error: This expression has type lit There is no field weight within type lit
Of course, from my point of view this was a rather obtuse analysis. This expression has a field “weight”, therefore why “infer” it was lit
, and not wit
which does have the required fields?
Very often these ill-inferences feature records with a common field like “name” or “index”, and perhaps that’s my error - i.e. Ocaml doesn’t really fully support that.
There’s also missing inference when a record is used prior to the place where its type is clearly established. E.g.,
let upw w = { w with weight = w.weight + 1 }
let uw i = let (wit: Witdef.wit) = { weight = i ; index = 0 }
in upw wit
;;
print_endline (string_of_int (uw 50).weight)
… And ocaml says,
1 | let upw w = { w with weight = w.weight + 1 }
^^^^^^
Error: Unbound record field weight
I’m obliged to explicitly declare (w: Witdef.wit)
, even though the it’s clear at some point in the compilation that uw
calls upw
with a record of that type.
If the alternative involved some way to write upw
so that it would function with all records having a field weight
of an integer type, I wouldn’t have a problem with that.