I have written this code which compiles and works perfectly in VS.NET 2010
module ConfigHandler
open System
open System.Xml
open System.Configuration
let GetConnectionString (key : string) =
ConfigurationManager.ConnectionStrings.Item(key).ConnectionString
however when I do a control + A and Alt + Enter to send this to FSI I get an error
ConfigHandler.fs(2,1): error FS0010: Unexpected start of structured construct in definition. Expected '=' or other token.
OK.
So I change my code to
module ConfigHandler =
open System
open System.Xml
open System.Configuration
let GetConnectionString (key : string) =
ConfigurationManager.ConnectionStrings.Item(key).ConnectionString
Now Control + A, Alt + Enter is successful and I FSI nicely tells me
module ConfigHandler = begin
val GetConnectionString : string -> string
end
However now If I try to compile my code in VS.NET 2010, I get an error message
Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'
How can I have both? Ability to compile in VS.NET and the ability to send modules to FSI?
There is a tiny -- but crucial -- difference between your two snippets of code which is to blame here.
F# has two ways to declare a module
. The first, a "top-level module", is declared like this:
module MyModule
// ... code goes here
The other way to declare a module is as a "local module", like so:
module MyModule =
// ... code goes here
The main differences between the "top-level" and "local" declarations are that the local declaration is followed by an =
sign and the code within a "local" module must be indented.
The reason you get the ConfigHandler.fs(2,1): error FS0010: Unexpected start of structured construct in definition. Expected '=' or other token.
message for the first snippet is that you can't declare top-level modules in fsi
.
When you added the =
sign to your module definition, it changed from a top-level module to a local module. From there, you got the 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'
because local modules must be nested within a top-level module or a namespace. fsi
doesn't allow you to define namespaces (or top-level modules), so if you want to copy-paste the entire file into fsi
the only way it'll work is if you use the compilation directives as @pad mentioned. Otherwise, you can simply copy-paste the local module definitions (without the containing namespace) into fsi
and they should work as expected.
Reference:
Modules (F#) on MSDN
The common solution is to keep the first example and create a fsx
file which references the module:
#load "ConfigHandler.fs"
You have advantage of loading multiple modules and writing plumbing code for experiment.
If you really want to load ConfigHandler.fs
directly to F# Interactive, you can use INTERACTIVE
symbol and compiler directives:
#if INTERACTIVE
#else
module ConfigHandler
#endif
which works for both fsi and fsc.