2009-05-31 8 views
23

ho visto la seguente chiamata di funzione in Yacfe example:{X} con il valore in 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; 

posso vedere una chiamata di funzione con il record inizializzato come primo argomento, e ast come secondo argomento.

Quello che non sono a conoscenza è la sintassi della forma:

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

Che cosa significa questo? So che un record può essere inizializzato come {name=value;name=value;...}, ma non ho familiarità con lo {X with name=value}, puoi dirmi cosa significa?

non riesco a trovare nella Ocaml Manual nulla di inizializzazione del valore del record giuridica diversa da quella seguente:

tuple

6.2.3 Records

valori record vengono etichettati di valori. Il valore del record scritto { field1 = v1; ...; fieldn = vn} associa il valore vi al record campo , per i = 1 ... n. L'implementazione corrente supporta i record con un massimo di 222 - 1 campi (4194303 campi).

Sarò felice se nella tua risposta includerai un riferimento alla sezione pertinente nel manuale OCaml.

risposta

34

Questo è talvolta chiamato "aggiornamento record" o "aggiornamento funzionale" o qualcosa del genere. Valuta un nuovo record dello stesso tipo di X e i cui campi sono inizializzati allo stesso modo di quelli in X, tranne quelli che sono elencati dopo "con", che sono inizializzati con quei valori dati.

È utile per i record immutabili, come un modo conveniente per prendere tale record e cambiare una o due cose su di esso (che in un linguaggio imperativo si trasformano tipicamente in campi), senza dover elencare tutti i campi che non sono cambiati.

È descritto nel manuale OCaml section 6.7.3, scorrere fino a "Record", secondo paragrafo.

Per coloro che hanno familiarità con Haskell, la sintassi OCaml

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

è lo stesso che la sintassi Haskell

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

Grazie. Come potrei fare su Google? È abbastanza profondo nel manuale, e non ho potuto trovarlo facilmente. –

+3

Non so come lo faresti su Google. Mi è appena capitato di sapere questo. Ma in cima a quella pagina (sezione 6.7) elenca la grammatica di tutte le espressioni valide in OCaml, quindi se vuoi capire un'espressione puoi iniziare da lì per prima, e se la vedi scorrere verso il basso fino alla parte appropriata che la descrive. E in generale, il capitolo 6 tratta vari aspetti della grammatica della lingua OCaml; ci sono sezioni che trattano espressioni di tipi, modelli, classi, moduli, ecc. Quindi, se hai bisogno di cercare qualcosa, inizierei qui nella sezione appropriata. – newacct

+0

Wow, non sapevo che avresti potuto elencare 'fieldn = expern;'. Grazie! –

14

per correggere la risposta precedente, il nuovo record non è sempre del stesso tipo del vecchio record. Per esempio, si può avere una cosa del genere:

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

Di conseguenza, old_t è di tipo string t, mentre new_t è di tipo int t.