2012-08-28 7 views
8

ich diesen Code geschrieben haben, die kompiliert und funktioniert perfekt in VS.NET 2010definieren Module VS.NET vs F # Interactive

module ConfigHandler 
open System 
open System.Xml 
open System.Configuration 

let GetConnectionString (key : string) = 
    ConfigurationManager.ConnectionStrings.Item(key).ConnectionString 

aber wenn ich eine Kontrolle + A tun und Alt + Enter dies FSI zu schicken Ich erhalte einen Fehler

ConfigHandler.fs (2,1): Fehler FS0010: Unerwarteter Start des strukturierten Konstrukts in der Definition. Erwartetes '=' oder anderes Token.

OK.

So ändere ich meinen Code

module ConfigHandler = 
    open System 
    open System.Xml 
    open System.Configuration 

    let GetConnectionString (key : string) = 
    ConfigurationManager.ConnectionStrings.Item(key).ConnectionString 

Jetzt Strg + A, Alt + Enter ist erfolgreich und ich FSI sagt mir schön

Modul ConfigHandler = beginnen val GetConnectionString: string -> string Ende

aber jetzt, wenn ich versuche, meinen Code in VS.NET 2010 zu kompilieren, erhalte ich eine Fehlermeldung

Dateien in Bibliotheken oder Anwendungen mit mehreren Dateien müssen mit einem Namespace oder einer Moduldeklaration beginnen, z. 'Namespace SomeNamespace.SubNamespace' oder 'Modul SomeNamespace.SomeModule'

Wie kann ich beides haben? Möglichkeit, in VS.NET zu kompilieren und Module an FSI zu senden?

Antwort

14

Es gibt einen winzigen - aber entscheidenden - Unterschied zwischen Ihren zwei Codeschnipsel, der hier verantwortlich ist.

F # hat zwei Möglichkeiten, eine module zu deklarieren. Die erste, ein „Top-Level-Modul“ wird wie folgt erklärt:

module MyModule 
// ... code goes here 

Der andere Weg, ein Modul ist als „lokaler Modul“, wie so zu erklären:

module MyModule = 
    // ... code goes here 

die Haupt Unterschiede zwischen den Deklarationen "top level" und "local" bestehen darin, dass auf die lokale Deklaration ein = Zeichen folgt und der Code innerhalb eines "lokalen" Moduls muss eingerückt werden.

Der Grund, warum Sie die Nachricht ConfigHandler.fs(2,1): error FS0010: Unexpected start of structured construct in definition. Expected '=' or other token. für das erste Snippet erhalten, ist, dass Sie Module der obersten Ebene in fsi nicht deklarieren können.

Wenn Sie das Zeichen = zu Ihrer Moduldefinition hinzugefügt haben, wurde es von einem Modul der obersten Ebene zu einem lokalen Modul geändert. Von dort haben Sie den Fehler Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule' erhalten, da lokale Module in einem Modul der obersten Ebene oder einem Namespace geschachtelt sein müssen. fsi erlaubt es nicht, Namespaces (oder Top-Level-Module) zu definieren. Wenn Sie also die gesamte Datei in fsi kopieren und kopieren möchten, funktioniert das nur, wenn Sie die Kompilierungsanweisungen als @pad verwenden. Andernfalls können Sie die lokalen Moduldefinitionen (ohne den enthaltenden Namespace) einfach in fsi kopieren und sie sollten wie erwartet funktionieren.

Referenz: Modules (F#) on MSDN

6

Die gemeinsame Lösung ist das erste Beispiel zu halten und eine fsx-Datei erstellen, die das Modul verweist:

#load "ConfigHandler.fs" 

Sie Vorteil mehrere Module zum Laden und Schreiben von Sanitär-Code haben für das Experiment.

Wenn Sie wirklich wollen ConfigHandler.fs direkt zu F # Interactive laden, können Sie INTERACTIVE Symbol verwenden und compiler directives:

#if INTERACTIVE 
#else 
module ConfigHandler 
#endif 

, die für beide fsi und fsc arbeitet.