Scenario-Based F# Interview Questions and Answers (2025)
Scenario-Based F# Interview Questions and Answers
Scenario 1: Designing an Immutable Domain Model
Q1: You're building a financial transaction system. How would you model a transaction immutably in F#?
Answer:
type Transaction = { Id: Guid FromAccount: string ToAccount: string Amount: decimal Timestamp: DateTime}
Why it matters:
F# favors immutability for safety and concurrency. An immutable domain model
prevents accidental state mutation, especially in multi-threaded systems like
financial applications.
Scenario 2: REST API for a Blog Using Giraffe
Q2: You’re building a blog platform. How would you handle a
GET /posts/{slug} route
using F# and Giraffe?
Answer (simplified):
let getPostHandler slug = fun (next: HttpFunc) (ctx: HttpContext) -> task { let post = getPostBySlug slug // Assume this is defined return! json post next ctx } let webApp = choose [ routef "/posts/%s" getPostHandler ]
Why it matters:
This tests your ability to build RESTful APIs using Giraffe's functional
routing and async handling.
Scenario 3: Pipeline for Processing Orders
Q3: You’re processing e-commerce orders in stages (validate → calculate tax → save). How would you design a pipeline in F#?
Answer:
let validateOrder order = if order.Amount <= 0m then Error "Invalid amount" else Ok order let calculateTax order = let tax = order.Amount * 0.1m { order with Tax = tax } |> Ok let saveOrder order = // Simulate DB save printfn "Saved order" Ok order let processOrder order = validateOrder order |> Result.bind calculateTax |> Result.bind saveOrder
Why it matters:
This uses function composition and error handling with Result, which are central to robust F#
programs.
Scenario 4: Handling Asynchronous Workflows
Q4: You need to fetch user data from a remote API and log it asynchronously. How do you handle this in F#?
Answer:
let fetchUserData userId = async { // Simulated async HTTP call return $"User {userId}"} let logData data = async { printfn "Logging: %s" data return ()} let handleUser userId = async { let! data = fetchUserData userId do! logData data}
Why it matters:
Tests understanding of F#’s async
workflows and coordination of side effects.
Scenario 5: Updating State with a Discriminated Union
Q5: You're implementing a state machine for an order. How do you model state transitions in F#?
Answer:
type OrderState = | Created | Paid | Shipped | Cancelled type OrderEvent = | Pay | Ship | Cancel let transition state event = match state, event with | Created, Pay -> Paid | Paid, Ship -> Shipped | _, Cancel -> Cancelled | _ -> state // Invalid transitions
Why it matters:
F# excels at modeling state transitions using pattern matching and DUs.
Scenario 6: Handling Errors Without Exceptions
Q6: You need to read a config file and parse its contents. How would you handle failure without exceptions?
Answer:
let readConfig path = try let content = System.IO.File.ReadAllText(path) Ok content with | :? System.IO.IOException as ex -> Error ex.Message
Why it matters:
Tests idiomatic error handling using Result
instead of exceptions.
Scenario 7: Parallelizing Computation
Q7: You have a list of URLs and need to download their HTML content in parallel. How do you do it in F#?
Answer:
let download url = async { use client = new System.Net.Http.HttpClient() let! html = client.GetStringAsync(url) |> Async.AwaitTask return (url, html)} let downloadAll urls = urls |> List.map download |> Async.Parallel |> Async.RunSynchronously
Why it matters:
F# makes parallelism composable and clean using Async.Parallel.
Bonus Tips for Interviews
· Show understanding of immutability, functional pipelines, and type safety.
· Use Discriminated Unions and Pattern Matching to model complex logic.
· Be familiar with Giraffe, Saturn, or Suave for web-based scenarios.
·
Understand how F# handles error
propagation (via Result<'a,
'b> or Option<'a>).
