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

{X со значением} в ocaml

Я видел следующий вызов функции в пример Yacfe:

  Visitor_c.vk_program { Visitor_c.default_visitor_c with
    Visitor_c.kexpr = (fun (k, bigf) exp -> 
      match Ast_c.unwrap_expr exp with
      | Binary(e1, Logical (Eq), (((Constant(Int("0")) as _e2),_t),ii)) -> 

          (match Ast_c.get_onlytype_expr e1 with 
          | Some (qu, (Pointer _,_ii)) -> 

              let idzero = Common.tuple_of_list1 ii in
              idzero.cocci_tag := 
                Ast_cocci.MINUS (Ast_cocci.NoPos, [[null_addon]]), [];

          | _ -> k exp
          )
      | _ -> k exp
    );
  } ast;

Я вижу вызов функции с записью, инициализированной как первый аргумент, и ast как второй аргумент.

Я не знаком с синтаксисом формы:

{Visitor_c.default_visitor_c with Visitor_c.kexpr = some_value;}

Что это значит? Я знаю, что запись может быть инициализирована как {name=value;name=value;...}, но я не знаком с {X with name=value}, можете ли вы сказать мне, что это значит?

Я не могу найти в Ocaml Manual ничего о инициализации значения легальной записи, кроме следующего:

6.2.3 Записи

Значения записи обозначены кортежами значения. Записанное значение записи { field1 = v1;...; fieldn = vn} связывает значение vi с записью поле fieldi, для я = 1... n. поддержка текущей реализации записи до 222 - 1 полей (4194303 полей).

Буду рад, если в вашем ответе вы включите ссылку на соответствующий раздел в руководстве OCaml.

4b9b3361

Ответ 1

Это иногда называется "обновление записи" или "функциональное обновление" или что-то в этом роде. Он оценивает новую запись того же типа, что и X, и поля которой инициализируются так же, как и в X, за исключением тех, которые перечислены после "с", которые инициализируются этими заданными значениями.

Он полезен для неизменяемых записей, как удобный способ взять такую ​​запись и изменить одну или две вещи на ней (которые на императивном языке, как правило, будут мутировать поля), не перечисляя все поля, которые не изменяются.

Это описано в руководстве OCaml раздел 6.7.3, прокрутите вниз до "Записи", второй абзац.

Для тех, кто знаком с Haskell, синтаксис OCaml

{ expr with field1 = expr1 ; ... ;  fieldn = exprn }

совпадает с синтаксисом Haskell

expr { field1 = expr1 , ... ,  fieldn = exprn }

Ответ 2

Чтобы исправить предыдущий ответ, новая запись не всегда имеет тот же тип, что и старая запись. Например, вы можете иметь что-то вроде этого:

type 'a t = {
  id : int;
  value : 'a;
}
let old_t = { id = 3; value = "foo" }
let new_t = { old_t with value = 3 }

В результате old_t имеет тип string t, а new_t имеет тип int t.