2011-10-27 1 views
5

Perché funziona correttamente?Utilizzo di unioni aperte esterne al modulo che erano state definite in

module Account = struct 

type account_type = Current of float | Savings of float 

end 

let sarah = Account.Current 100.0;; 

Mentre la linea finale nel seguente produce un Error: syntax error?

module Account = struct 

    type 'a account_type = [> `Current of float | `Savings of float ] as 'a 

end 

let pete = Account.`Current 100.0;; 

Ovvero, perché non è possibile utilizzare il tipo di unione aperta all'esterno del modulo senza aprire il modulo? Devo dire che ho scoperto che cambiando la linea finale:

open Account;; 
let pete = `Current 100.0;; 

funziona bene, ma ovviamente questo è ingombrante se uso account_type un sacco, o, in alternativa devo aprire Account all'inizio di qualsiasi codice sezione dove viene utilizzato account_type, il che significa che sacrificherei l'astrazione che otterrei usando una firma per Account
Ho navigato attraverso diversi tutorial di OCaml così come la documentazione INRIA, e non riesco a trovare alcuna menzione di come lo fai
E 'possibile evitare di dover aprire il modulo ogni volta che voglio usare un account_type?

Grazie in anticipo,

Zach

risposta

6

Nel secondo esempio, che in realtà non c'è bisogno di open Account a tutti, la sintassi è solo `Current 100.0. Un tag variante polymorphic non partecipa a nessun tipo particolare. Il tipo di `Current è [> `Current ], questo (il >) indica che il tipo è almeno `Current e poiché si tratta di un sottoinsieme del tipo accettato dalla funzione, verrà compilato correttamente. È possibile passare lo stesso valore a un numero di funzioni che accettano una variante polimorfica con lo stesso nome. Naturalmente, mancano informazioni di tipo statico e errori e situazioni di digitazione possono diventare piuttosto complessi.

Code Reuse through polymorphic variants parla di alcuni vantaggi e casi d'uso per loro.

5

Le costanti di varianti polimorfiche come `Current sono definite globalmente, in modo simile alle costanti integer. Non si direbbe Account.10 per fare riferimento al numero intero 10 nel modulo Account.

Questa è la forza (e la debolezza) delle varianti polimorfiche, è possibile utilizzarle senza definirle (come non è necessario definire 10 prima di utilizzarle).

Quindi, come dice nlucaroni, non è necessario aprire il modulo Account per accedere a `Current.

A differenza degli interi, le varianti polimorfiche possono anche assumere parametri (come nel tuo `Current 100.0). Ma il numero di parametri e il loro tipo non sono fissi, e possono anche variare per lo stesso costruttore in diversi punti del codice. Da qui le complessità menzionate anche da nlucaroni.

[Nota di formattazione: per ottenere singoli backquote ` da visualizzare con il testo in stile macchina da scrivere, la convenzione per il markdown prevede l'utilizzo di backquotes doppi per racchiudere il testo. Questo lascia solo backquote all'interno del testo. O almeno sta funzionando per me.]

+0

Ah, ho provato a sfuggire il backtick con un backtick, causando così tanta confusione per tutte le persone coinvolte. – nlucaroni