chore: import upstream snapshot with attribution
CI / Test (ubuntu-latest, Node 18.x, bun) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, npm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, pnpm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, yarn) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 20.x, bun) (push) Failing after 17m13s
CI / Test (ubuntu-latest, Node 20.x, npm) (push) Failing after 18m42s
CI / Test (ubuntu-latest, Node 20.x, pnpm) (push) Failing after 15m0s
CI / Test (ubuntu-latest, Node 20.x, yarn) (push) Failing after 49m44s
CI / Test (ubuntu-latest, Node 22.x, bun) (push) Failing after 51m55s
CI / Test (ubuntu-latest, Node 22.x, pnpm) (push) Failing after 21m57s
CI / Test (ubuntu-latest, Node 22.x, npm) (push) Failing after 37m39s
CI / Test (ubuntu-latest, Node 22.x, yarn) (push) Failing after 34m7s
CI / Validate Components (push) Failing after 37m15s
CI / Python Tests (push) Failing after 10m1s
CI / Security Scan (push) Failing after 10m1s
CI / Lint (push) Failing after 17m12s
CI / Coverage (push) Failing after 20m19s
CI / Test (macos-latest, Node 18.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, yarn) (push) Has been cancelled
CI / Test (ubuntu-latest, Node 18.x, bun) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, npm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, pnpm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, yarn) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 20.x, bun) (push) Failing after 17m13s
CI / Test (ubuntu-latest, Node 20.x, npm) (push) Failing after 18m42s
CI / Test (ubuntu-latest, Node 20.x, pnpm) (push) Failing after 15m0s
CI / Test (ubuntu-latest, Node 20.x, yarn) (push) Failing after 49m44s
CI / Test (ubuntu-latest, Node 22.x, bun) (push) Failing after 51m55s
CI / Test (ubuntu-latest, Node 22.x, pnpm) (push) Failing after 21m57s
CI / Test (ubuntu-latest, Node 22.x, npm) (push) Failing after 37m39s
CI / Test (ubuntu-latest, Node 22.x, yarn) (push) Failing after 34m7s
CI / Validate Components (push) Failing after 37m15s
CI / Python Tests (push) Failing after 10m1s
CI / Security Scan (push) Failing after 10m1s
CI / Lint (push) Failing after 17m12s
CI / Coverage (push) Failing after 20m19s
CI / Test (macos-latest, Node 18.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, yarn) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
---
|
||||
paths:
|
||||
- "**/*.fs"
|
||||
- "**/*.fsx"
|
||||
---
|
||||
# F# Coding Style
|
||||
|
||||
> This file extends [common/coding-style.md](../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 `mutable` only 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
|
||||
|
||||
```fsharp
|
||||
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 `with` expressions for updates
|
||||
- Prefer `list`, `map`, `set` over mutable collections
|
||||
- Avoid `ref` cells and mutable fields in domain logic
|
||||
|
||||
```fsharp
|
||||
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 `Option` instead of null; use `Result` for operations that can fail
|
||||
|
||||
```fsharp
|
||||
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 `CancellationToken` through public async APIs
|
||||
- Prefer `Result` and railway-oriented programming over exceptions for expected failures
|
||||
|
||||
```fsharp
|
||||
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 `fantomas` for automatic formatting
|
||||
- Prefer significant whitespace; avoid unnecessary parentheses
|
||||
- Remove unused `open` declarations
|
||||
|
||||
### Open Declaration Order
|
||||
|
||||
Group `open` statements into four sections separated by a blank line, each section sorted lexically within itself:
|
||||
|
||||
1. `System.*`
|
||||
2. `Microsoft.*`
|
||||
3. Third-party namespaces
|
||||
4. First-party / project namespaces
|
||||
|
||||
```fsharp
|
||||
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
|
||||
```
|
||||
Reference in New Issue
Block a user