{X со значением} в ocaml - PullRequest
28 голосов
/ 31 мая 2009

Я видел следующий вызов функции в примере 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 ничего о законной инициализации значения записи, кроме следующего:

6.2.3 Записи

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

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

Ответы [ 2 ]

39 голосов
/ 31 мая 2009

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

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

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

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

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

соответствует синтаксису Haskell

expr { field1 = expr1 , ... ,  fieldn = exprn }
15 голосов
/ 17 февраля 2012

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

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...