2012-08-28 11 views
8

He escrito el código que compila y funciona perfectamente en VS.NET sin embargo 2010Definición de módulos VS.NET vs F # Interactivo

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

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

cuando hago un control + A y Alt + Enter para enviar esto a FSI Obtengo un error

ConfigHandler.fs (2,1): error FS0010: Comienzo inesperado de constructo estructurado en la definición. Se espera '=' u otro token.

OK.

Así que cambiar el código para

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

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

Ahora Control + A, Alt + Enter es exitosa y yo bien me FSI dice

módulo ConfigHandler = comienzan val GetConnectionString: cadena -> cadena terminar

Sin embargo ahora si intento compilar mi código en VS.NET 2010, me sale un mensaje de error

Los archivos en bibliotecas o aplicaciones de archivos múltiples deben comenzar con un espacio de nombres o una declaración de módulo, p. 'namespace SomeNamespace.SubNamespace' o 'module SomeNamespace.SomeModule'

¿Cómo puedo tener ambos? Posibilidad de compilar en VS.NET y la capacidad de enviar módulos a FSI?

Respuesta

14

Hay una pequeña pero crucial diferencia entre los dos fragmentos de código que es el culpable aquí.

F # tiene dos formas de declarar module. La primera, un "módulo de nivel superior", se declara así:

module MyModule 
// ... code goes here 

La otra manera de declarar un módulo es como un "módulo local", así:

module MyModule = 
    // ... code goes here 

La principal las diferencias entre las declaraciones de "nivel superior" y "local" son que la declaración local es seguida por un signo = y el código dentro de un módulo "local" debe tener una sangría de.

El motivo por el que recibe el mensaje ConfigHandler.fs(2,1): error FS0010: Unexpected start of structured construct in definition. Expected '=' or other token. para el primer fragmento es que no puede declarar módulos de nivel superior en fsi.

Cuando agregó el signo = a su definición de módulo, cambió de un módulo de nivel superior a un módulo local. A partir de ahí, obtuvo el error Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule' porque los módulos locales deben estar anidados dentro de un módulo de nivel superior o un espacio de nombres. fsi no le permite definir espacios de nombres (o módulos de nivel superior), por lo que si desea copiar y pegar todo el archivo en fsi, la única forma en que funcionará es si usa las directivas de compilación como se menciona en @pad. De lo contrario, simplemente puede copiar y pegar las definiciones de los módulos locales (sin el espacio de nombres que lo contiene) en fsi y deberían funcionar como se esperaba.

Referencia: Modules (F#) on MSDN

6

La solución común es mantener el primer ejemplo y crear un archivo fsx que hace referencia al módulo:

#load "ConfigHandler.fs" 

Usted tiene la ventaja de cargar múltiples módulos y escribir código de plomería para el experimento.

Si realmente desea cargar ConfigHandler.fs directamente a F # interactiva, puede utilizar INTERACTIVE símbolo y compiler directives:

#if INTERACTIVE 
#else 
module ConfigHandler 
#endif 

que funciona tanto para FSI y FSC.

Cuestiones relacionadas