rules/fsharp/coding-style.md
This file extends common/coding-style.md with F#-specific content.
mutable only when justified by performancetype EmailAddress = EmailAddress of string
type OrderStatus =
| Pending
| Confirmed of confirmedAt: DateTimeOffset
| Shipped of trackingNumber: string
| Cancelled of reason: string
type Order =
{ Id: Guid
CustomerId: string
Status: OrderStatus
Items: OrderItem list }
with expressions for updateslist, map, set over mutable collectionsref cells and mutable fields in domain logiclet rename (profile: UserProfile) newName =
{ profile with Name = newName }
|> to build readable data pipelinesOption instead of null; use Result for operations that can faillet processOrder order =
order
|> validateItems
|> Result.bind calculateTotal
|> Result.map applyDiscount
|> Result.mapError OrderError
task { } for interop with .NET async APIsasync { } for F#-native async workflowsCancellationToken through public async APIsResult and railway-oriented programming over exceptions for expected failureslet loadOrderAsync (orderId: Guid) (ct: CancellationToken) =
task {
let! order = repository.FindAsync(orderId, ct)
return
order
|> Option.defaultWith (fun () ->
failwith $"Order {orderId} was not found.")
}
fantomas for automatic formattingopen declarationsGroup open statements into four sections separated by a blank line, each section sorted lexically within itself:
System.*Microsoft.*open System
open System.Collections.Generic
open System.Threading.Tasks
open Microsoft.AspNetCore.Http
open Microsoft.Extensions.Logging
open FsCheck.Xunit
open Swensen.Unquote
open MyApp.Domain
open MyApp.Infrastructure