2009-05-31 18 views
23

vi la siguiente llamada a la función en Yacfe example:{X} con el valor en ocaml

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; 

Veo una llamada de función con el registro inicializado como primer argumento, y ast como segundo argumento.

lo que no estoy familiarizado con la sintaxis es de la forma:

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

¿Qué significa esto? Sé que se puede inicializar un registro como {name=value;name=value;...}, pero no estoy familiarizado con el {X with name=value}, ¿me puede decir lo que significa?

no puedo encontrar en el Ocaml Manual nada de valor de registro legal de inicialización excepción de las siguientes:

tuplas

6.2.3 Registros

valores de registros se etiquetan de valores. El valor de registro escrito { campo1 = v1; ...; fieldn = vn} asocia el valor vi al registro campo fieldi, para i = 1 ... n. La implementación actual admite registros con hasta 222 - 1 campos (4194303 campos).

Estaré encantado de que en su respuesta incluya una referencia a la sección correspondiente en el manual OCaml.

Respuesta

34

Esto a veces se denomina "actualización de registro" o "actualización funcional" o algo así. Evalúa a un nuevo registro del mismo tipo que X, y cuyos campos se inicializan al mismo que aquellos en X, excepto los que se enumeran después del "con", que se inicializan a esos valores dados.

Es útil para registros inmutables, como una forma conveniente de tomar ese registro y cambiar uno o dos elementos (lo que en un lenguaje imperativo normalmente cambiaría los campos), sin tener que enumerar todos los campos que no son cambiados

Se describe en el manual OCaml section 6.7.3, desplácese hacia abajo a "Registros", segundo párrafo.

Para aquellos que están familiarizados con Haskell, la sintaxis OCaml

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

es la misma que la sintaxis de Haskell

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

Gracias. ¿Cómo podría google eso? Es bastante profundo en el manual, y no pude encontrarlo fácilmente. –

+3

No sé cómo lo googlearías. Yo solo sabía esto. Pero en la parte superior de esa página (sección 6.7) enumera la gramática de todas las expresiones que son válidas en OCaml, por lo que si quiere comprender una expresión, puede comenzar allí primero, y si la ve, desplácese hacia abajo hasta la parte apropiada que la describe. Y en general, el Capítulo 6 trata de varios aspectos de la gramática del lenguaje OCaml; hay secciones que tratan con expresiones de tipos, patrones, clases, módulos, etc. Por lo tanto, si necesita buscar algo, comenzaría primero en la sección correspondiente. – newacct

+0

Guau, no sabía que podría seguir enumerando 'fieldn = expern;'. ¡Gracias! –

14

Para corregir la respuesta anterior, el nuevo registro no es siempre de la mismo tipo que el registro anterior. Por ejemplo, puede tener algo así:

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

Como resultado, old_t es de tipo string t, mientras new_t es de tipo int t.