F#: Why are these brackets necessary (syntax) - f#

Just for my own peace of mind, I am wondering why, in last line, in my AssemblyInfo.fs file, it is neccessary to add a () in order for it to compile. What do you call this syntax?
namespace TestComComponentFSharp
open System.Reflection
open System.Runtime.CompilerServices
open System.Runtime.InteropServices
[<assembly: AssemblyTitle("TestComComponentFSharp")>]
[<assembly: ComVisible(true)>]
[<assembly: Guid("0B684F15-DC37-40C0-A785-EDF1A63BBAF5")>]
[<assembly: AssemblyKeyFile("KeyFile.snk")>]
[<assembly: AssemblyVersion("1.0.0.0")>]
[<assembly: AssemblyFileVersion("1.0.0.0")>]
()

You need something to apply those assembly attributes to. That whats the empty () or do() is for. Its called an "Empty Expression" - it returns a unit.

Related

F# Interactive with nuget reference: namespace not defined

I am trying to use the Select.HtmlToPdf library https://www.nuget.org/packages/Select.HtmlToPdf/20.2.0
#r "nuget: Select.HtmlToPdf, 20.2.0"
open Select.HtmlToPdf
After sending the reference to the FSI, it returns a path to ...\Project.fsproj.fsx and namespace FSI_0004.Project
After sending the open statement to FSI, I get
The namespace or module "Select" is not defined.
I am pretty new to F#, hope somebody can explain how I have to do this.
Thanks
EDIT: I use Visual Studio Code and/or Jupyter lab
The library is called Select.HtmlToPdf, but the namespace it uses is SelectPdf, so this should work:
#r "nuget: Select.HtmlToPdf, 20.2.0"
open SelectPdf

Documentation/List of standard preprocessing symbols

As an example, I'm using the following preprocessing directive
#if COMPILED
let context = Sql.GetDataContext(ConfigurationManager.ConnectionStrings.[AppDB].ConnectionString)
#else
let context = Sql.GetDataContext()
#endif
so that I'm able to test a dll library from F# interactive, to give you an idea
#I #"bin\Debug"
#r #"import.dll"
#r #"FSharp.Data.SqlProvider.dll"
#load "Library1.fs"
open SqlLib
open SqlDB
// Define your library scripting code here
let book = "My Company"
let db = DB()
db.analysts book |> Array.iter (printfn "%A")
because, of course, in the example above ConfigurationManager would not be usable from the scripting engine, so I need to implement a change at preprocessing time.
More generally, where can I find the documentation or a at least a list of all the available, standard symbols, that are already automatically defined, including COMPILED and so on...?
From Compiler directives F#:
Symbols that you use in the if directive must be defined by the command line or in the project settings; there is no define preprocessor directive...
When VERSION1 is defined by using the -define compiler option, the code between the #if directive and the #else directive is activated. Otherwise, the code between #else and #endif is activated.
So you can defined your own preprocessor directives when compile code. If you work with .NET Core, inside fsproj or csproj you can define these symbols as:
<PropertyGroup Condition="'$(TargetFramework)' != 'net40'">
<DefineConstants>NET45</DefineConstants>
</PropertyGroup>
dotnet sends them to fsc. If you curious what symbols are defined by default, you can investigate fsc source code
I found COMPILED and INTERACTIVE there.

Using ConfigurationManger in F# project

I am simply trying to use the ConfigurationManager within an F# project but I am getting the error:
This value is not a function and cannot be applied
here is the code:
open System.Configuration
let connectionString = ConfigurationManager.ConnectionStrings["ManagementDb"].ConnectionString
I have also referenced the System.Configuration library.
I haven't verified this in Visual Studio, but usually there is a dot ('.') when using an F# index.
i.e.
let connectionString = ConfigurationManager.ConnectionStrings.["ManagementDb"].ConnectionString

Referencing external assembly fails

I can't get referencing a private assembly working. I've followed the documentation, but it still fails with the error message:
2016-09-29T19:43:08.615 startup(2,1): error FS82: Could not resolve this reference. Could not locate the assembly "Backend.dll". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. (Code=MSB3245)
Here is the run.fsx file:
#r "Backend.dll"
open System
open System.IO
open System.Net
open System.Net.Http.Headers
open System.Collections.Generic
open CoP
let createResponse json =
let responseJson = Request.handleJson json
let response = new HttpResponseMessage()
response.Content <- new StringContent(responseJson)
response.StatusCode <- HttpStatusCode.OK
response.Content.Headers.ContentType <- MediaTypeHeaderValue("application/json")
response
let Run (req: HttpRequestMessage) =
async {
let! json = req.Content.ReadAsStringAsync()
return createResponse json
} |> Async.StartAsTask
I've also placed the Backend.dll in a bin folder inside the same folder as the function.
What am I missing?
Looks like you ran into a bug with private assembly resolution in the Azure Functions F# implementation.
I've opened this issue for tracking and will have a fix included in the next release:
https://github.com/Azure/azure-webjobs-sdk-script/issues/733
In the meantime, you should be able to reference your private assembly by using:
#r "bin/Backend.dll"
Hope this helps!
If that was a question about .fsx scripts alone, I'd say you're missing the part where you tell FSI where to look for the dll to reference:
#I "bin"
#r "BackEnd.dll"
Is there anything Azure does to put the .\bin folder within the context reachable by #r directive?

F# Module/Namespace Error

My first program with F#.
I have one file like so:
namespace LanguageMapper.Data
#if INTERACTIVE
#r "System.Data"
#r "System.Data.Linq"
#r "FSharp.Data.TypeProviders"
#endif
open System.Data
open System.Data.Linq
open Microsoft.FSharp.Data.TypeProviders
module Data =
// You can use Server Explorer to build your ConnectionString.
type SqlConnection = Microsoft.FSharp.Data.TypeProviders.SqlDataConnection<ConnectionString = #"connstring">
let db = SqlConnection.GetDataContext()
Then i have another file like so
namespace LanguageMapper.Program
open Data
module Program =
[<EntryPoint>]
let main argv =
let getLocale x =
match x with
| [|"live"|] -> "live"
| [|"dev"|] -> "dev"
| _ -> "local"
Over top of the open Data i get a red squiggly in VS telling me:
"Error 1 This declaration opens the namespace or module
'Microsoft.FSharp.Data' through a partially qualified path. Adjust
this code to use the full path of the namespace. This change will make
your code more robust as new constructs are added to the F# and CLI
libraries."
What am i doing wrong? I just want to reference one file from the other.
You need to open the module using its fully qualified name, that is including its namespace. So in LanguageMapper.Program you need to open LanguageMapper.Data.Data (only the last bit is the module name).
The Compiler is complaining on your open definition because it only specifies to open a namespace or module named Data - and it finds one in Microsoft.FSharp.Data, probably because there are some 'automatic' opens for the Microsoft.FSharp namespaces.

Resources