Our journey to F#: libraries we use

When I started with F#, I had some problems to find good libraries for the stuff we need in our software. Sometimes the problem was to find a library at all, sometimes several libraries provide similar functionality. So here is a list of the libraries I like to use (what we use and why).

Argu

Argu (pronounced “Argue”) is a declarative CLI argument parser for F# console applications. It allows modelling the command-line syntax using discriminated unions, which the library converts into a working parser using reflection. [from the Argu website]

Argu is a simple to use command line argument parser that I use for all our Command Line tools written in F#.

Dapper – a simple object mapper for .Net

We used Dapper in our C# code so we continued using it. It can easily be used from F#. You can for example use anonymous records to pass SQL parameters to Dapper. Dapper is fast and simple and you keep full control over your queries. We don’t use any of the extensions.

FluentAssertions

A very extensive set of extension methods that allow you to more naturally specify the expected outcome of a TDD or BDD-style unit tests. [from FluentAssertions’ website]

We have a mix of F# and C# code so we cannot simply use FsUnit (see below) for all our test assertions. When we have a mixed value graph containing F# records and C# objects, we use FluentAssertions’ structural comparison feature Should().BeEquivalentTo.

We built some wrapper methods to make FluentAssertion easier to use from F# code. You can find them here.

FSharp.Control.FusionTasks

  • Easy interoperability .NET Task/ValueTask <–> F#’s Async.
  • F# async workflow block now support direct .NET Task/ValueTask handle with let!, do! and use!.
  • .NET (C# async-await) now support directly F#’s Async.
  • SyncronizationContext capture operation support (F#: AsyncConfigure method / .NET (C#) AsAsyncConfigured method)

FSharpx.Extras

We use the string functions from FSharpx.Extras providing F# friendly wrappers for common string manipulations like split, trim and so on.

And the library helps us with interop between C# and F#: converting Actions to Functions, Nullables to Options, creating F#-lists and so on.

FsToolkit.ErrorHandling

FsToolkit.ErrorHandling is a utility library to work with the Result type in F#, and allows you to do clear, simple and powerful error handling. [from FsToolkit’s website]

We heavily use FsToolkit-ErrorHandling. It helps us with its computation expressions to handle error cases with ease. A very common scenario for us is that we need to load some data and if it exists and if it is valid then we do some compute on it. The CEs provided for Result, Option, Async and all combinations help a lot.

FsUnit.xUnit

FsUnit is a set of libraries that makes unit-testing with F# more enjoyable. It adds a special syntax to your favorite .NET testing framework. FsUnit currently supports NUnit, xUnit, and MsTest. [from FsUnit’s website]

We use FsUnit for our test assertions for code that is F# only. It is simple to and proved okay error messages. If you look for an assertion library with better error messages, you may have to take a look at Expecto or Unquote (see below).

Since we run all C# tests with xUnit, FsUnit.xUnit was an easy choice for us.

NodaTime

Noda Time is an alternative date and time API for .NET. It helps you to think about your data more clearly, and express operations on that data more precisely. [from NodaTime’s website]

In our system – a time tracking software – we have to deal with time a lot. Therefore, NodaTime is the obvious choice because dealing with time is much easier than with the tools the .Net standard libraries provide.

NodaTime is also easy to be used from F# code.

Polly

Polly is a .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner. [from Polly’s website]

We use Polly for all out-of-process communications. While the API doesn’t feel that F#-ish, using Polly really is no problem from F#. If you prefer an F#-y API, then give Pholly a try (I didn’t have the time yet to take a look and refactor our code).

Thoth.Json

Thoth is a JSON serializer and deserializer and provides manual and auto de-/encoder.

We use Thoth to serialize and deserialize data into our storages and to send data to our web clients (this is however a bit more complex because we use Thoth and Newtonsoft.Json side-by-side because we have a mix of C# and F#).

Thoth can handle all F# data types including discriminated unions.

Unquote

Unquote, takes advantage of F# quotations to allow you to write test assertions as plain, statically checked F# boolean expressions and automatically produces nice step-by-step test failure messages.

We don’t use Unquote (yet) because we most of the times have a mix of C# and F# code and therefore use FluentAssertions and its structural comparison of C# objects.

xUnit

xUnit.net is a free, open source, community-focused unit testing tool for the .NET Framework. [from xUnit’s website]

We use xUnit because all our C# tests are run with it and it can easily be used from F#. It supports async workflows and can execute them directly:

[<Fact>]
let ``my test`` () =
    async {
        do! Async.Sleep 42
    }

That’s all for today. Happy coding!

Find all blog posts about our journey to F# here.

This blog post is made possible with the support of Time Rocket, the product this journey is all about. Take a look (German only).

About the author

Urs Enzler

3 comments

By Urs Enzler

Recent Posts