Подтвердить что ты не робот

В чем смысл предупреждения 40: эта запись... содержит поля, которые не видны в текущей области

Обратите внимание на следующий код:

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 = "" }

Два модуля определяют точно такую ​​же запись. Функция f преобразует запись A в запись B. Предупреждение уже выдается во время компиляции, но также доступно в интерактивном режиме. В ocaml cli кажется, что вызов f делает предполагаемое:

# 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 = ""}

Я нашел запись в блоге lexifi.com, которая объясняет проблему и некоторые распространенные решения. То, что я не понимаю, является фактическим сообщением об ошибке:

  • Что означает, что тип становится неизвестным?
  • Что означает, когда поле не выбрано?
  • И в результате двух выше: какие условия необходимо выполнить, чтобы игнорировать предупреждение?
4b9b3361

Ответ 1

Тип записи известен в этом случае, потому что вы предоставили аннотации. Если вы удалите аннотации, тип станет неизвестным, и значение кода может измениться.

Философия OCaml заключается в том, что добавление и удаление аннотаций типа не должно влиять на смысл программы, поэтому возникает предупреждение.

Вы можете избежать этого предупреждения, введя соответствующее поле в область видимости. Выполнение этого для поля, которое определено в модуле A, включает либо открытие A, чтобы привести его содержимое в область видимости, либо определить имя поля с модулем. Например:

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