Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the meaning of Warning 40: this record ... contains fields that are not visible in the current scope

Tags:

ocaml

Please consider the following code:

module A =
  struct
    type r = { i : int; s: string }
  end

module B =
  struct
    type r = { i : int; s : string }
  end


let f (x : A.r) : B.r = match x with
    { i; s } -> { i = 2*i; s = "" }

Two modules define exactly the same record. A function f converts an A record to a B record. The warning is already emitted during compilation, but also visible interactively. On the ocaml cli, it seems that a call to f does the intended thing:

# let x = f { i = 5; s = "ab" };;
Characters 10-29:
  let x = f { i = 5; s = "ab" };;
            ^^^^^^^^^^^^^^^^^^^
Warning 40: this record of type Shadow.A.r contains fields that are 
not visible in the current scope: i s.
They will not be selected if the type becomes unknown.
val x : Shadow.B.r = {Shadow.B.i = 10; s = ""}

I found a blog posting on lexifi.com which explains the problem and some common solutions. What i don't understand is the actual error message:

  • What does it mean that a type becomes unknown?
  • What does it mean when a field is not selected?
  • And resulting from the two above: which conditions need to be satisfied to ignore the warning?
like image 576
lambda.xy.x Avatar asked Apr 14 '15 10:04

lambda.xy.x


1 Answers

The type of the record is known in this case because you provided annotations. If you removed the annotations, the type would become unknown and the meaning of the code might change.

The philosophy of OCaml is that adding and removing type annotations should not affect the meaning of a program, so a warning is produced.

You can avoid this warning by bringing the relevant field into scope. Doing this for a field that is defined within a module A entails either opening A to bring its contents into scope, or qualifying the name of field with the module. For example:

module A = struct ... end

let test r = r.A.field

let test2 r = let open A in r.field

open A 

let test3 r = r.field
like image 191
gsg Avatar answered Jan 06 '23 08:01

gsg