2014-06-18 14 views
11

C'è un modo per condividere i tipi tra file fsx?Condivisione di tipi su file F # .fsx

Quando si utilizza #load per caricare lo stesso file contenente un tipo da più file FSX, sembra che ogni volta siano prefissati in un diverso spazio dei nomi FS_00xx, il che significa che non è possibile passarli.

Esistono modi per aggirare questo comportamento senza ricorrere alla compilazione in un assembly?

+4

Forse con moduli in file '.fs'? – NoIdeaHowToFixThis

+0

@NoIdeaHowToFixQuesto ha già provato varie combinazioni di moduli e spazi dei nomi - non sembra avere alcun effetto - gli spazi dei nomi vengono semplicemente preceduti con FS_00xx invece –

+0

Puoi pubblicare del codice dove vengono visualizzati questi spazi dei nomi FS_00xx? Se uso un file '.fs' con un namespace, funziona bene: http://pastebin.com/QZ2m0WUe –

risposta

8

Per quanto riguarda

http://msdn.microsoft.com/en-us/library/dd233169.aspx

[file .fsx vengono] utilizzati per includere il codice di prova informale in F # senza aggiungere il codice di test per la vostra applicazione, e senza creare un progetto separato per esso. Per impostazione predefinita, i file di script non sono inclusi nella build di un progetto anche quando fanno parte di un progetto.

Questo significa che se si dispone di un progetto con la struttura sufficiente per essere avere tali problemi con le dipendenze, non si dovrebbe usare .fsx file, anziché scrivere moduli/namespace usando .fs file. Cioè, dovresti davvero compilarli in un assembly.

L'interprete interattivo f # genera l'assembly per ogni file caricato. Se si carica un file due volte, il bytecode viene generato due volte e i tipi sono diversi anche se hanno la stessa definizione e lo stesso nome. Ciò significa che non è possibile condividere tipi tra due file .fsx, a meno che uno di essi non includa l'altro.

Quando si #load un file che ha lo stesso tipo come quelli già presenti nel proprio ambiente, l'interprete interattivo F # è possibile utilizzare due strategia diversa:

  1. rifiutano di caricare il file se i conflitti con i nomi esistenti si pone (lamentando che alcuni elementi siano già definiti)
  2. inserire i nomi nello spazio dei nomi FS_00xx (in modo che siano in realtà tipi diversi da quelli già caricati), eventualmente open nello spazio dei nomi risultante in modo che i nomi siano disponibili dalla sessione interattiva.

Dal file FSX dovrebbero essere utilizzati come prova informale è più user-friendly per usare il secondo approccio (ci sono anche ragione tecnica per cui viene utilizzato il secondo approccio, prevalentemente a carico .net tipo VM sistema e il fatto che i tipi esistenti non possono essere modificati in fase di runtime).

1

avere tutte le #load e #open direttive nel file che si esegue dalla fsi.exe (C nell'esempio qui sotto), e assicurarsi che i file caricati stessi non #load proprie dipendenze:

file A. fsx, B.fsx, C.fsx. B dipende da A. C dipende da B e A.

B contiene

//adding the code below would cause the types defined in A to be loaded twice 
//#load "A.fsx" 
//#open A 

C contiene

#load "A.fsx" 
#open A 
#load "B.fsx" 
#open B 

Purtroppo questo allora fa tutti i file difficile da modificare da Visual Studio - l'editor non sa circa le loro dipendenze e mostra tutti i tipi di errori.

Quindi questo è un po 'di un hack, e il modo consigliato sembra essere quello di avere un unico file .fsx e compilare tutto il resto in una dll:

// file1.fsx 
#r "MyAssembly.dll" 

https://msdn.microsoft.com/en-us/library/dd233175.aspx

+0

è questa un'altra domanda o un commento? Sembra non essere una risposta (o è?) – Carsten

+0

nel caso in cui sia un'altra domanda: dovresti chiederlo da solo - ma per aiutarti un po ': .fsx dovrebbero essere file singoli - se vuoi una struttura di progetto con più file che dipendono l'uno dall'altro dovresti ... beh .. creare un progetto e usare i file .fs (vedi la * risposta * pqnet fornita sopra) – Carsten

+0

@Carsten Ho modificato la risposta per farla sembrare più simile una risposta (sì, inizialmente avrei fatto una nuova domanda, ma dopo aver suggerito utilmente questa domanda simile, ho trovato la mia soluzione) – Ande

5

[Nota:. si tratta di una risposta più specifica a un more specific question che è un duplicato di questo]

Non penso che ci sia una soluzione semplice e piacevole per questo. L'unica soluzione che ho utilizzato in alcuni progetti (come the F# snippets web site) consiste nell'avere un solo file di livello superiore fsx che carichi un numero di file fs. Ad esempio, vedere app.fsx.

Quindi, si avrebbe common.fs, intMapper.fs e stringMapper.fs che sarebbe caricato da caller.fsx come segue:

#load "common.fs" 
#load "stringMapper.fs" 
#load "intMapper.fs" 
open Common 

All'interno stringMapper.fs e intMapper.fs, fare non carico common.fs. I tipi comuni verranno caricati da caller.fsx prima, quindi le cose funzioneranno.

L'unico problema con questo è che intMapper.fs ora non è un file di script autonomo e se si desidera ottenere il completamento automatico in un editor, è necessario aggiungere un file fsproj che specifica l'ordine dei file. Nel progetto F # snippet, c'è a project file che specifica l'ordine in cui l'editor dovrebbe vedere e caricare i file.

Problemi correlati