I created a new F# library with say the following expressions:
module Module1
let x = 2 + 2
When trying to run this, I get an error
Unexpected start of structured construct in definition. Expected '=' or other token.
When you say "run", do you mean select all -> ALT + ENTER to send to FSI? If so, I think that is your issue. FSI doesn't handle file-level module declarations. You need to either not select module Module1 when you send it to FSI, or change it to a module expression:
module Module1 =
let x = 2 + 2
Related
So I'm running the following code from the FParsec sample, but it doesn't seem to want to run.
namespace Test
open FParsec.CharParsers
module Stuff =
let main = run pfloat "1.25E3"
let str s = pstring s
let floatBetweenBrackets = str "[" >>. pfloat .>> str "]"
The problem is the last line - I get this error:
Error 1 Expecting a type supporting the operator '>>.' but given a function type. You may be missing an argument to a function. C:\Users\...\Documents\Visual Studio 2013\Projects\Solution2\ConsoleApplication1\load.fs 6 42 Formatting
The code is from here:
http://www.quanttec.com/fparsec/tutorial.html#parsing-a-float-between-brackets
If it matters, the version of F# I'm running is:
Microsoft (R) F# Interactive version 12.0.30110.0
>>. is defined in FParsec.Primitives, so you need to open that as well. Alternatively, you can just open FParsec, since
Opening the FParsec namespace also automatically opens the Primitives, CharParsers and Error modules.
This answer explains why the error you're seeing is what it is.
I am trying to set up a tiny F# console app with FSharp.Data referenced in the solution. I got the following error at runtime :
An unhandled exception of type 'System.TypeInitializationException' occurred in Anot_F1.exe
for this code (error in line 4) :
1 open FSharp.Data
2 type Anot_lines = CsvProvider<"anot1.csv",Separators=";">
3 let ll = Anot_lines.Load("anot1.csv")
4 for r in ll.Rows do
5 printfn "%A" r.ToString
In debug mode after line 3, I can see that the variable ll contains the proper Headers but does not show the rows.
My CSV file is :
tline;tcol;bline;bcol;anot
3;1;4;16;"Barack Obama has ... The US president"
3;1;3;12;"Barack Obama"
3;18;3;26;"ratcheted"
4;102;4;109;"agencies"
4;289;4;306;"financial pressure"
4;1;4;320;"The US president ...ure on the regime"
4;1;4;16;"The US president"
I am new to F# and especially have no experience on using type providers.
Any help greatly appreciated.
The issue is with line 3, you're using a method that loads CSV data from a URL. You need to use the GetSample() method. Also note that the "%A" format placeholder can print any value and doesn't require a ToString() call.
let ll = Anot_lines.GetSample()
for r in ll.Rows do
printfn "%A" r
UPDATE
The general question is: how to use verbose syntax of F# correctly? Verbose syntax is the syntax which is close to OCaml syntax, i.e. syntax with many commas etc.
OLD TEXT
I want to turn light syntax off in F# to have verbose syntax which is closer to OCaml.
I wrote the following code
#light "off"
let k=3.14;;
and got an error on let:
Unexpected keyword 'let' or 'use' in implementation file
What is correct implementation file structure without light syntax?
The problem is that you have written this inside a .fsi file - which is an FSharp Interface definition file; it has nothing to do with fsi.exe (FSharp Interactive).
The message "Unexpected keyword 'let' or 'use' in implementation file" is a tell - interface definitions were expected. Simply use a .fs extension.
If you want reuse ML code, consider changing the file extension to .ml, and add a #nowarn "62" directive at the beginning to ignore the legacy warning.
#nowarn "62"
#light "off"
let div2 = 2;;
let f x =
let r = x % div2 in
if r = 1 then
begin "Odd" end
else
begin "Even" end
I don't see anything wrong but... why the two ;? Are you compiling it or running in fsi?
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.
If I compile the following module into a dll
namespace MyNs
module SomeModule =
do printfn "module loading"
let x = 23
then reference the dll in FSI and execute the command open MyNs.SomeModule "module loading" does not print immediately. It only prints when I access x which causes all the top level let and do bindings to execute (normal behavior I know in the .NET world). Is there any way, perhaps via an attribute on the module, I can indicate that module should load immediately upon opening in FSI?
Opening a module never does anything at runtime. It just puts all the symbols in the opened namespace in scope for unqualified access below the open statement.
Section 12.5 of the language spec is what you want to read - this details when the static initialization of a module will run.
Given that, the only time when this initialization is run automatically, as far as I know, is for last module in an exe.
I.e. I don't think there is a direct way to accomplish what you want.
If you have reflective access to the module:
ModuleType.TypeInitializer.Invoke(null, null)
will invoke the static initialization.
You can add the AutoOpen attribute to the module
[<AutoOpen>]
module SomeModule =
do printfn "module loading"
let x = 23
However this will only print the module loading message when you reference x.
Not sure if you found the solution to your problem but in my case I wanted to start an agent when my website was starting and it was indeed starting twice like you mentioned.
What I did was set a method let start() = inside the module and invoke the method using a static do xxx.start() from my main Site type.
Found that by reading the language spec Kurt linked.