error FS0039: The field, constructor or member 'X' is not defined - f#

I am trying to run my code interactively in an fsx file. I have loaded all the dlls required, I then try to load the required files with #load but when I load the "Utlities.fs" file which depends on a function in the top file "HttpGetExchangeRate.fs" i get the error "Utilities.fs(88,42): error FS0039: The field, constructor or member 'getExchangeRates' is not defined"
Dose the 'getExchangeRates' not get defined when i load "HttpGetExchangeRate.fs"as in the image below or an I missing something?
#load "HttpGetExchangeRate.fs"
#load "Utilities.fs"
open System
open FsCheck
open NUnit.Framework
open HttpClient
InvoiceApp.Http.getExchangeRates "EUR" "USD"
InvoiceApp.Math.convertInvoicingCurrencyToEuro 200.00M "EUR"
Here is an image of the error message

If I understand your scenario correctly, this is due to a bug in how namespaces are handled in FSI. The workaround is to open the namespace you need before #loading the second file
#load "HttpGetExchangeRate.fs"
open InvoiceApp
#load "Utilities.fs"
That should get you unblocked for now, the bug has since been fixed (F# 4.0/VS 2015 will have the fix).

It sounds like you are running into the issue described in this question with implicit modules in fsi.
How to load external F# code and use it in fsi

Related

This expression was expected to have type 'System.String' but here has type 'string'

How is it possible that the F# compiler rejects the type string when it's expecting a System.String?
#I #"..\..\packages"
#r #"FSharp.Data\lib\net40\FSharp.Data.dll"
open FSharp.Data
let [<Literal>] csvFile = #"..\..\data\FootballResults.csv"
type Football = CsvProvider< csvFile >
let data = Football.GetSample().Rows |> Seq.toArray
After running this simple code, I get the error message:
Script.fsx(5,30): error FS0001: This expression was expected to have type 'System.String' but here has type 'string'
I thought string was simply an alias for System.String?
Edit
The csv file is quite big, just the first rows are important:
Date,Home Team,Away Team,Full Time Home Goals,Full Time Away Goals,Full Time Result,Half Time Home Goals,Half Time Away Goals,Half Time Result,Home Shots,Away Shots,Home Shots on Target,Away Shots on Target,Home Fouls,Away Fouls,Home Cards,Away Cards,Home Yellow Cards,Away Yellow Cards,Home Red Cards,Away Red Cards
08/18/2012,Arsenal,Sunderland,0,0,D,0,0,D,14,3,4,2,12,8,7,0,0,0,0,0
08/18/2012,Fulham,Norwich,5,0,H,2,0,H,11,4,9,2,12,11,6,3,0,0,0,0
08/18/2012,Newcastle,Tottenham,2,1,H,0,0,D,6,12,4,6,12,8,3,5,2,2,0,0
The full file can be downloaded here under the folder data
FSharp.Data version
FSharp.Data 2.3.2
I found the problem, it was in the paket script provided in the book Get Programming with F#.
The script was pointing to an old version of FSharp.Data (I thought paket was this amazing package manager that always get you the best version for your project while in fact, it does not, you always fight and struggle with wrong dependencies).
At the end I managed to fix the problem this way:
Solution 1
Simply start a new project using the nuget command Install-Package FSharp.Data -Version 4.2.7 and then the reference to the package #r "nuget: FSharp.Data"
Solution 2
Update the paket.lock provided by the book with the correct version FSharp.Data (4.2.7). The code posted in my question run after that.
Advice for F# learner
Whoever is trying to learn F# with this book, it's a good book but be very careful with their package reference. They seem outdated and can get you into unpleasant situation.

F# Interactive CsvProvider not defined

I'm loading FSharp.Data in the interactive console. The library is loaded without any problem:
> #r "FSharp.Data.dll";;
--> Referenced 'C:\Users\pw\AppData\Local\Temp\FSharp.Data.dll' (file may be locked by F# Interactive process)
> open FSharp.Data;;
However, when I'm trying to initialize CsvProvider (defined in FSharp.Data) I get the error message saying the type is not defined:
> type Stocks = CsvProvider<"C:\Users\pw\Downloads\msft.csv">;;
type Stocks = CsvProvider<"C:\Users\pw\Downloads\msft.csv">;;
--------------^^^^^^^^^^^
stdin(62,15): error FS0039: The type 'CsvProvider' is not defined
I thought the problem may be with file and assemblies paths but now I'm using absolute paths and the error remains. On the other hand, I am able to use the CsvProvider when I'm creating a standard, not interactive, project. Any help to make it work in interactive session highly appreciated.
The warning about file being locked looks worrisome. Can you copy FSharp.Data somewhere and reference it using absolute path:
\#r #"C:\Poligon\packages\FSharp.Data.2.1.0\lib\net40\FSharp.Data.dll";;
Downgrade your FSharp.Core to 4.7 and FSharp.Data to 3.3.3. It should work after that.

The value or constructor 'DotCoverNUnit' is not defined

We're using Fake and I'd like to run DotCover after our Build target. It's alway telling me:
C:\Users\xxxxx\Dev>FAKE\tools\Fake build.fsx
F# Interactive for F# 3.1 (private)
Freely distributed under the Apache 2.0 Open Source License
For help type #help;;
> [Loading C:\Users\xxxxx\Dev\build.fsx]
build.fsx(8,1): error FS0039: The value or constructor 'DotCoverNUnit' is not defined
My short simple "test" script
#r #"FAKE/tools/FakeLib.dll"
open Fake
DotCoverNUnit dotCoverOptions nUnitOptions
What went wrong?
You need to open namespace containing DotCoverNUnit class:
open Fake.DotCover

DomainTypes in XmlProvider FS0039 not defined

I am trying to use the FSharp.Data XmlProvider.
According to the samples you can access nested types and create a function that will receive a parameter of one of those types.
https://github.com/fsharp/FSharp.Data/blob/master/samples/library/XmlProvider.fsx (line 177)
However when I try to do the following:
type businessesT = XmlProvider<"Businesses.xml">
type businessT = businessesT.DomainTypes.Business
let testfunc (b:businessesT.DomainTypes.Business) =
b
It seems to work until I actually compiles and then I get
error FS0039: The type 'Business' is not defined
UPDATE:
The problem can be reproduced with the sample from FSharp.Data (XmlProvider.fsx)
adding a type alias after line 205
type Rss = XmlProvider<"http://tomasp.net/blog/rss.aspx">
type test = Rss.DomainTypes.Channel
What is strange is that the sample with the printDiv function is working...
This is most likely caused by some problem with loading the type provider - if the compiler fails to load the type provider, then it cannot run it and so none of the provided types like Business would be defined.
Are you using #r in a script file, or are you referencing the type provider through "Add References" in a project? If you're using #r, check if there is any error message on that line. In case of project, check other error messages output by the compiler.
I already listed some common reasons why type provider fails to load in another answer.
This was probably the same problem as "type provider" not recognized when building project, which has been fixed in FSharp.Data 1.1.10

Is there any way to force load a module when it is opened through FSI?

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.

Resources