mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-05-13 18:00:35 +08:00
2.8 KiB
2.8 KiB
paths
| paths | ||
|---|---|---|
|
F# Coding Style
This file extends common/coding-style.md with F#-specific content.
Standards
- Follow standard F# conventions and leverage the type system for correctness
- Prefer immutability by default; use
mutableonly when justified by performance - Keep modules focused and cohesive
Types and Models
- Prefer discriminated unions for domain modeling over class hierarchies
- Use records for data with named fields
- Use single-case unions for type-safe wrappers around primitives
- Avoid classes unless interop or mutable state requires them
type 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 }
Immutability
- Records are immutable by default; use
withexpressions for updates - Prefer
list,map,setover mutable collections - Avoid
refcells and mutable fields in domain logic
let rename (profile: UserProfile) newName =
{ profile with Name = newName }
Function Style
- Prefer small, composable functions over large methods
- Use the pipe operator
|>to build readable data pipelines - Prefer pattern matching over if/else chains
- Use
Optioninstead of null; useResultfor operations that can fail
let processOrder order =
order
|> validateItems
|> Result.bind calculateTotal
|> Result.map applyDiscount
|> Result.mapError OrderError
Async and Error Handling
- Use
task { }for interop with .NET async APIs - Use
async { }for F#-native async workflows - Propagate
CancellationTokenthrough public async APIs - Prefer
Resultand railway-oriented programming over exceptions for expected failures
let loadOrderAsync (orderId: Guid) (ct: CancellationToken) =
task {
let! order = repository.FindAsync(orderId, ct)
return
order
|> Option.defaultWith (fun () ->
failwith $"Order {orderId} was not found.")
}
Formatting
- Use
fantomasfor automatic formatting - Prefer significant whitespace; avoid unnecessary parentheses
- Remove unused
opendeclarations
Open Declaration Order
Group open statements into four sections separated by a blank line, each section sorted lexically within itself:
System.*Microsoft.*- Third-party namespaces
- First-party / project namespaces
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