2012-08-28 23 views
8

我寫了這個代碼,編譯,當我做了控制+ A和Alt + Enter鍵發送這FSI在VS.NET完美的作品2010定義模塊VS.NET VS F#互動

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

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

然而,我收到錯誤

ConfigHandler.fs(2,1):錯誤FS0010:定義中的結構化構造的意外啓動。預期的'='或其他令牌。

好的。

所以我我的代碼更改爲

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

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

現在控制+ A,Alt + Enter鍵是成功的,我FSI很好地告訴我

模塊ConfigHandler =開始 VAL GetConnectionString:字符串 - >字符串 end

但是現在如果我嘗試在VS.NET 2010中編譯我的代碼,我收到一條錯誤消息

庫或多文件應用程序中的文件必須以名稱空間或模塊聲明開始,例如'namespace SomeNamespace.SubNamespace'或'module SomeNamespace.SomeModule'

我該怎麼做?能夠在VS.NET中編譯並能夠將模塊發送到FSI?

回答

14

你的兩個代碼片段之間有一個很小但很關鍵的區別,這就是責任。

F#有兩種方法可以聲明module。首先,一個「頂層模塊」,聲明如下:

module MyModule 
// ... code goes here 

其他方式來聲明一個模塊是作爲一個「本地模塊」,就像這樣:

module MyModule = 
    // ... code goes here 

主要「頂級」和「本地」聲明之間的區別在於,本地聲明後跟=符號,並且「本地」模塊必須中的代碼被縮進。

您得到第一個片段的ConfigHandler.fs(2,1): error FS0010: Unexpected start of structured construct in definition. Expected '=' or other token.消息的原因是您無法聲明fsi中的頂級模塊。

當您將=符號添加到模塊定義中時,它將從頂層模塊更改爲本地模塊。從那裏,你得到了錯誤Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule',因爲本地模塊必須嵌套在頂層模塊或命名空間中。 fsi不允許您定義名稱空間(或頂級模塊),因此如果您想將整個文件複製粘貼到fsi,它的工作方式唯一的方法是如果您使用編譯指令作爲@pad提到的。否則,您可以簡單地將本地模塊定義(不包含包含名稱空間)複製粘貼到fsi中,並且它們應該按預期工作。

參考: Modules (F#) on MSDN

6

常見的解決辦法是讓第一個例子,並創建一個fsx文件,該文件引用模塊:

#load "ConfigHandler.fs" 

你有優勢,加載多個模塊和編寫相關的代碼進行實驗。

如果你真的想直接加載到ConfigHandler.fs F#互動,您可以使用INTERACTIVE符號和compiler directives

#if INTERACTIVE 
#else 
module ConfigHandler 
#endif 

它同時適用於FSI和FSC。