F# in VSCode from Scratch

F# in VSCode from Scratch

FAKE and Paket vs Rust Cargo

There's an Ionide plugin and Ionide-FAKE and Ionide-Paket

dotnet new lists all templates

# Create a F# Console Application
dotnet new console -lang F# -o src/MyConsoleApp

# Create a class library
dotnet new classlib -lang F# -o src/MyLibrary

Editing the fsproj file

In MyLibrary.fsproj xml add:

<ItemGroup>
    <Compile Include="Library.fs" />
    <Compile Include="NewFile.fs" />
  </ItemGroup>

To add MyLibrary.fsproj to MyConsoleApp.fsproj add:

<ItemGroup>
      <ProjectReference Include="..\MyLibrary\MyLibrary.fsproj" />
  </ItemGroup>

or run

dotnet add src/MyConsoleApp/MyConsoleApp.fsproj reference src/MyLibrary/MyLibrary.fsproj

Building

To build, run:

dotnet build src/MyConsoleApp/MyConsoleApp.fsproj

This gives you a .dll file to run:

dotnet src/MyConsoleApp/bin/Debug/netcoreapp3.0/MyConsoleApp.dll

Running

dotnet run -p src/MyConsoleApp/MyConsoleApp.fsproj Scott

This runs your console application with args Scott.

Add Nuget References

Add reference to MyConsoleApp.fsproj:

<ItemGroup>
    <PackageReference Include="Argu" Version="5.0.1" />
</ItemGroup>
  • If you get warning Detected package downgrade: FSharp.Core, add a <PackageReference> to FSharp.Core
    • Add minimum version: <PackageReference Include="FSharp.Core" Version="4.3.2" />

Alternatively run

dotnet add src/MyConsoleApp/MyConsoleApp.fsproj package Argu

# if you have package downgrade error.
dotnet add src/MyConsoleApp/MyConsoleApp.fsproj package FSharp.Core

Package References with Paket

Run:

paket init
paket add --project src/MyConsoleApp/MyConsoleApp.fsproj Argu

It automatically handles dependencies! Wow!

If you have nuget packages, you can convert with:

paket convert-from-nuget

Adding Tests with Expecto

We can write it manually:

dotnet new console -lang F# -o tests/MyTests
dotnet add tests/MyTests/MyTests.fsproj package Expecto
dotnet restore tests/MyTests/MyTests.fsproj

And edit Program.fs to:

open Expecto

[<EntryPoint>]
let main argv =
    Tests.runTestsInAssembly defaultConfig argv

Finally run:

dotnet run -p tests/MyTests/MyTests.fsproj

Using Expecto Template

This feels better.

dotnet new -i Expecto.Template::12.0.0
dotnet new expecto -o tests/MyTests

dotnet run -p tests/MyTests/MyTests.fsproj

F# Ecosystem vs Rust's Cargo

Paket

# init paket
paket init

# add a dependency
paket add <package> -p <project>
# or 
paket add <package> -i #(to be prompted on which projects need to have the reference added

# remove a dependency
paket remove <package>

# update all dependencies
paket update

# update single dependencies
paket update <package>

Running

# packaging?
dotnet pack

# publish for deployment?
dotnet publish

# build
dotnet build

# run
dotnet run

FAKE

For complex MAKE like build, packaging, deployment, and testing, however you can also just call CLI tools.

In essence, it's a scripting tool.