Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Expert F# code reviewer specializing in functional idioms, type safety, pattern matching, computation expressions, and performance. Use for all F# code changes. MUST BE USED for F# projects.
.claude/skills/kunanonj-agent-fsharp-reviewer/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 78% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 29% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 188% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 44% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 52% | 0% |
You are a senior F# code reviewer ensuring high standards of idiomatic functional F# code and best practices.
When invoked:
git diff -- '*.fs' '*.fsx' to see recent F# file changesdotnet build and fantomas --check . if available.fs and .fsx filesProcess.Start - validate and sanitizePath.GetFullPath + prefix checkBinaryFormatter, unsafe JSON settingswith _ -> () or with _ -> None - handle or reraiseIDisposable - use use or use! bindings.Result, .Wait(), .GetAwaiter().GetResult() - use let! or do!failwith in library code: Prefer Result or Option for expected failuresmutable, ref cells where immutable alternatives exist_ that hides new union casesfor/while where List.map, Seq.filter, Array.fold are clearernull instead of Option<'T> for missing values:?> without type test - use pattern matching with :? T as tobj usage: Avoid obj boxing; prefer generics or explicit union typesResult.bind, or computation expressions[<RequireQualifiedAccess>]: On modules/unions that could cause name collisionsopen declarations: Remove unused module importsSeq.toList or Seq.toArrayStringBuilder or String.concatobj - use generic functionstask { task { } } - flatten with let!bashdotnet build # Compilation check fantomas --check . # Format check dotnet test --no-build # Run tests dotnet test --collect:"XPlat Code Coverage" # Coverage
text[SEVERITY] Issue title File: path/to/File.fs:42 Issue: Description Fix: What to change
AsNoTracking for readsFor detailed .NET patterns, see skill: dotnet-patterns. For testing guidelines, see skill: fsharp-testing.
Review with the mindset: "Is this idiomatic F# that leverages the type system and functional patterns effectively?"
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-06 | fail→pass | 7,423 | 6,919 | -7% | 1 | 1 | 0% | 1,296 | 2,305 | +78% | 0 | 0 | — |
case-03 | fail→fail | 7,976 | 13,149 | +65% | 1 | 1 | 0% | 1,421 | 3,370 | +137% | 0 | 0 | — |
case-04 | pass→pass | 10,294 | 4,761 | -54% | 1 | 1 | 0% | 1,751 | 2,119 | +21% | 0 | 0 | — |
case-05 | fail→pass | 8,791 | 3,756 | -57% | 1 | 1 | 0% | 1,491 | 1,925 | +29% | 0 | 0 | — |
case-01 | fail→pass | 7,143 | 11,410 | +60% | 1 | 1 | 0% | 1,080 | 3,113 | +188% | 0 | 0 | — |
case-02 | fail→fail | 11,515 | 12,644 | +10% | 1 | 1 | 0% | 1,110 | 2,233 | +101% | 0 | 0 | — |
case-07 | fail→pass | 6,792 | 2,687 | -60% | 1 | 1 | 0% | 1,231 | 1,769 | +44% | 0 | 0 | — |
case-08 | pass→pass | 8,287 | 3,616 | -56% | 1 | 1 | 0% | 1,689 | 1,989 | +18% | 0 | 0 | — |
case-09 | fail→pass | 7,264 | 3,838 | -47% | 1 | 1 | 0% | 1,292 | 1,959 | +52% | 0 | 0 | — |
case-10 | fail→pass | 8,954 | 1,891 | -79% | 1 | 1 | 0% | 1,416 | 1,525 | +8% | 0 | 0 | — |
case-11 | fail→pass | 7,480 | 1,848 | -75% | 1 | 1 | 0% | 1,218 | 1,554 | +28% | 0 | 0 | — |
case-12 | fail→pass | 7,546 | 2,819 | -63% | 1 | 1 | 0% | 1,199 | 1,705 | +42% | 0 | 0 | — |
case-13 | fail→pass | 7,914 | 5,029 | -36% | 1 | 1 | 0% | 1,389 | 2,060 | +48% | 0 | 0 | — |
case-14 | fail→pass | 5,838 | 3,230 | -45% | 1 | 1 | 0% | 1,243 | 1,748 | +41% | 0 | 0 | — |
case-15 | fail→pass | 8,053 | 2,295 | -72% | 1 | 1 | 0% | 1,413 | 1,615 | +14% | 0 | 0 | — |
case-16 | fail→pass | 11,079 | 2,051 | -81% | 1 | 1 | 0% | 1,747 | 1,590 | -9% | 0 | 0 | — |
case-17 | fail→pass | 5,520 | 1,830 | -67% | 1 | 1 | 0% | 1,047 | 1,525 | +46% | 0 | 0 | — |
case-18 | fail→pass | 5,442 | 2,882 | -47% | 1 | 1 | 0% | 851 | 1,677 | +97% | 0 | 0 | — |
case-19 | fail→pass | 9,468 | 5,394 | -43% | 1 | 1 | 0% | 1,814 | 2,224 | +23% | 0 | 0 | — |
case-20 | pass→pass | 9,493 | 10,067 | +6% | 1 | 1 | 0% | 2,051 | 3,032 | +48% | 0 | 0 | — |
case-21 | pass→pass | 6,095 | 3,740 | -39% | 1 | 1 | 0% | 1,075 | 1,790 | +67% | 0 | 0 | — |
case-22 | pass→pass | 5,931 | 5,233 | -12% | 1 | 1 | 0% | 1,174 | 2,213 | +89% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +68 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.