Chapter C3
F# for Elixir developers
You already think functionally. This chapter maps what you know onto a typed runtime.
If you write Elixir, F# will feel familiar long before it feels foreign: immutability by
default, pattern matching, and the very same |> pipe. This chapter is the
Elixir-community parallel to C2 · F# for C# developers — it takes each habit
you carry from the BEAM and shows its idiomatic F# form on the CLR. The genuine shift is the type system:
F# infers a static type for everything and checks your matches for exhaustiveness. Nine modules, three dives each.
The same ideas, a typed home
Elixir and F# are both functional-first languages with immutable data, first-class functions, and pattern matching at the centre. Elixir runs on the BEAM and stays dynamically typed; F# runs on the .NET CLR and is statically typed with full inference. So most of the vocabulary transfers directly — and where it changes, the change is usually the compiler doing more for you.
Select a concept below to see it both ways: the Elixir you would write, beside its idiomatic F# form. Both snippets are real and runnable. The full module directory follows.
The bridge · select a concept
Elixir
# Elixir [1, 2, 3, 4, 5] |> Enum.map(fn x -> x * 2 end) |> Enum.sum() # => 30
F#
// F# [ 1; 2; 3; 4; 5 ] |> List.map (fun x -> x * 2) |> List.sum // val it : int = 30
Coming from Elixir, the surprise is how little is new — and that the new part, static types, mostly shows up as the compiler catching what you would have caught in a test.
The nine modules
Each module takes one Elixir habit and lands it in F#, three dives at a time. The last is a hands-on lab: a first .NET app, end to end.
Two functional runtimes — the BEAM & the CLR
What carries over from the BEAM, and what the managed runtime changes.
From dynamic to static types
Type inference, and making illegal states unrepresentable.
Pattern matching, sharpened
Familiar ground, plus exhaustiveness and active patterns.
The pipe you already know (+ composition)
The same |>, plus forward composition >>.
Tuples & atoms → records & unions
Typed product and sum types for tuples and atoms.
{:ok, _} / {:error, _} → Result & Option
The tagged tuples you return, as types.
Processes & GenServer → MailboxProcessor
F#’s actor, async workflows, and what OTP adds.
Protocols & behaviours → interfaces
Interfaces and object expressions for protocols.
Mix & OTP → dotnet & .NET
A lab: the dotnet CLI, project structure, a first app.
References
Sources
- Microsoft — F# documentation — the language guide and reference.
- The F# Software Foundation — the language's home and community.
- F# Core Library reference —
List,Option,Result,MailboxProcessor. - Microsoft — .NET documentation — the CLR and the runtime that hosts F#.
Related in this course
- F# In Depth — course home — the full C0–C5 map.
- C2 — F# for C# developers — the sibling bridge, for the other community.
- Functional Programming in Elixir — the course these habits come from.
- Elixir F3 — The Elixir Language — processes, pattern matching, OTP, for comparison.