Appendices: Projects, Interview Questions, Cheat Sheet & Study Plan

Capstone projects, interview questions, an F# cheat sheet, F# for developers coming from other languages, and resources with a study plan.

Appendix A: Capstone Projects

Beginner: Command-Line Calculator. Parse expressions with active patterns into a union AST, evaluate with pattern matching, and handle errors with Result.

Beginner: To-Do CLI. Records, unions for commands, JSON persistence with System.Text.Json + FSharp.SystemTextJson, and Argu for argument parsing.

Intermediate: Bank Account Domain. Constrained types, smart constructors, a railway-oriented validation pipeline, a MailboxProcessor for concurrency, and Expecto + FsCheck tests.

Intermediate: Data Analysis Script. CSV/JSON type providers, Deedle aggregation, and Plotly.NET charts in a Polyglot notebook.

Intermediate: Concurrent Web Scraper. task { } + HttpClient, parallel fetching with throttling, HTML parsing (FSharp.Data HtmlProvider or AngleSharp).

Intermediate: Units-Safe Physics Simulator. Units of measure, immutable state updates, and a simple render loop.

Advanced: REST API. Giraffe or Oxpecker + Dapper/SqlHydra + PostgreSQL, validation, authentication, OpenAPI, Docker, and CI.

Advanced: Full-Stack SAFE App. Saturn + Fable + Elmish + Fable.Remoting with shared domain types.

Advanced: Custom Computation Expression DSL. A workflow or parser CE (or use FParsec) for a small configuration language.

Advanced: Event-Sourced System. Unions as events, folds for state rebuilding, Marten or an in-memory event store, and projections.

Desktop: Avalonia.FuncUI App. An MVU desktop app (e.g., a Markdown notes editor) with file persistence.

Open Source: Publish a NuGet Library. Documented with FsDocs, formatted with Fantomas, tested with Expecto, and CI-published to NuGet.

Appendix B: Interview Questions

What is F#, and how does it relate to OCaml and .NET?

What does "functional-first" mean?

Explain type inference in F#. When do you need annotations?

What is currying and partial application?

Explain |>, >>, and <|.

Why is F# file and declaration order significant?

What is unit? What does ignore do?

How do let, let mutable, and ref differ?

Types and Matching Records vs classes vs anonymous records vs struct records?

What are discriminated unions? Give a domain-modeling example.

Explain pattern matching and exhaustiveness checking.

What are active patterns (complete, partial, parameterized, single-case)?

Option vs ValueOption vs null?

How does Result support error handling? What is railway-oriented programming?

What are units of measure? Do they exist at runtime?

What does "make illegal states unrepresentable" mean? Show an example.

Collections and Functions List vs array vs seq: performance characteristics and when to use each?

How do you write tail-recursive functions? What does [<TailCall>] do?

Explain fold, foldBack, reduce, scan, choose, and collect.

Map/Set vs Dictionary/HashSet?

What are computation expressions? How do you build one (Bind, Return, ...)?

async { } vs task { }: hot vs cold, cancellation, performance?

What is MailboxProcessor, and when do you use it?

What are type providers? Give examples.

What are inline functions and SRTP?

How do you interoperate with C# (exposing APIs, nulls, out parameters, [<CLIMutable>])?

What are quotations used for?

How does nullness checking work in F# 9?

Explain object expressions and interface implementation in F#.

How do you do dependency injection functionally?

How do you test F# code? What is property-based testing?

What are Fable and Elmish (MVU)?

Model a shopping cart with unions (Empty | Active | Paid) and implement addItem and pay.

Implement a binary search tree with insert, contains, and in-order traversal.

Write a CSV parser returning Result<Row list, ParseError>.

Write a result { } computation expression builder.

Implement word frequency counting with a pipeline and countBy.

Write a MailboxProcessor-based cache with expiry.

Write FsCheck properties for a sorting function.

Implement FizzBuzz with a parameterized active pattern.

Appendix C: F# Cheat Sheet

// ===== Bindings and functions =====
let x = 1   let mutable y = 0   y <- 1   let f a b = a + b   let g = fun x -> x * 2   let rec h n = ...
let add5 = f 5   (f 1 2)   (+) 1 2   let inline sq x = x * x

// ===== Pipelines =====
xs |> List.map f |> List.filter p |> List.sum   (f >> g) x   f <| x   (a, b) ||> f

// ===== Types =====
type R = { A: int; B: string }   let r = { A = 1; B = "x" }   { r with A = 2 }
type U = Case1 | Case2 of int | Case3 of x: float * y: float
type W = W of string                       // single-case wrapper
type C(arg: int) = member _.P = arg        // class
type I = abstract M: int -> int            // interface
[<Measure>] type m                         // unit of measure

// ===== Pattern matching =====
match v with | 0 -> "zero" | n when n < 0 -> "neg" | _ -> "pos"
match xs with [] -> 0 | h :: t -> h
match o with :? string as s -> s | _ -> ""
let (|Even|Odd|) n = if n % 2 = 0 then Even else Odd
let (|Int|_|) (s: string) = match System.Int32.TryParse s with | true, v -> Some v | _ -> None

// ===== Option / Result =====
Some 1 |> Option.map f |> Option.defaultValue 0   Ok 1 |> Result.bind g |> Result.mapError h

// ===== Collections =====
[1; 2; 3]  [1
…
dotnet new console -lang F#   dotnet run   dotnet fsi script.fsx   dotnet test   dotnet add package X   dotnet fantomas .

Appendix D: F# for Other Developers

int Add(int a, int b) add a b = a + b def add(a, b): let add a b = a + b lambda x: x * 2 fun x -> x * 2 string?, null Option, ValueOption record Person(...) data/record types type Person = {... }

Class hierarchies (C# lacks native unions) switch expressions match... with |> pipelines, List/Seq modules async { } / task { } Mutable by default Immutable by default Reference (classes) Structural for records/unions Key gotchas:

= is equality (not assignment); assignment to mutables uses <-; inequality is <>.

Indentation is significant; use spaces, not tabs.

File order matters in the project file.

No implicit numeric conversions (float 1 + 2.0).

List elements are separated by ; (or newlines), not ,: [1, 2] is a list containing one tuple!

Method calls on .NET objects use tupled arguments: obj.Method(a, b), while F# functions are curried: f a b.

Appendix E: Resources and Study Plan

fsharp.org (F# Software Foundation), learn.microsoft.com/dotnet/fsharp (docs, tour, style guide, language reference), github.com/dotnet/fsharp (compiler, RFCs in fslang-design), fsprojects organization, Amplifying F# community initiative

F# for Fun and Profit (Scott Wlaschin's site: free, essential reading)

*Domain Modeling Made Functional* (Scott Wlaschin) *Get Programming with F#* (Isaac Abraham) *F# in Action* (Isaac Abraham) *Stylish F#* (Kit Eason) *Expert F#* (Don Syme et al.)

*Essential F#* (Ian Russell, free e-book) *F# Deep Dives* (Petricek & Skeet, eds.)

*Real-World Functional Programming* (Petricek & Skeet) *The Book of F#* (Dave Fancher)

F# Slack (FSSF), the F# Discord, r/fsharp, Amplifying F# sessions, Fable/SAFE community, the F# Weekly newsletter (Sergey Tihon), fsharpConf, NDC/.NET Conf F# talks, and Exercism's F# track 12-Week Study Plan

Setup, FSI and scripts, values and types, functions Pipelines, control flow, strings, tuples

Records, unions, pattern matching, Option Result, active patterns, units of measure

Lists, arrays, sequences, maps/sets, recursion, folds Modules, projects and file order, exceptions, mutability, I/O and JSON

Domain modeling, railway-oriented programming, functional architecture

Computation expressions, custom builders, async, tasks Agents, parallelism, classes, interfaces and inheritance

Generics/SRTP, structs and interop, type providers, quotations

Testing, FsCheck, tooling, performance, web development 47–52 + Capstone

Databases, Fable/Elmish, UI, data science, deployment, internals

Final tip: Let the types do the work. Model your domain with records and unions, keep functions small and pure, and pipe data through transformations. Master pattern matching, Option/Result, computation expressions, and domain modeling, and F# will make your .NET code shorter, safer, and a joy to maintain. Happy coding! 🔷