Conversation
396bce5 to
84fb50a
Compare
| * [map2](job/map2.md) | ||
| * [map3](job/map3.md) | ||
| * [singleton](job/singleton.md) | ||
| * [result](job/result.md) |
There was a problem hiding this comment.
we could just remove this as this is the builtin one from Hopac
| [<System.Obsolete "Use JobOption.some instead (aligns with AsyncResult naming)">] | ||
| let inline singleton x = some x | ||
|
|
||
| //TODO should these be added alongside all `some` ? |
| map box input1 | ||
| map box input2 | ||
| |], | ||
| maxDegreeOfParallelism = 2 |
There was a problem hiding this comment.
does not achieve anything
|
@TheAngryByrd still WIP but worth a review now:
|
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved critical build and cancellation issues remain, along with moderate documentation and test-target defects.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds .NET 10/FSharp.Core 11 interoperability, compatibility shims for older targets, API renames, and related test and documentation updates.
Changes:
- Adds conditional Async/Task shims and .NET 10 targeting.
- Aligns constructors and exception-handling APIs with FSharp.Core conventions.
- Updates source, tests, build configuration, benchmarks, and documentation.
File summaries
| File | Reviewed changes and findings |
|---|---|
tests/FsToolkit.ErrorHandling.Tests/TaskValueOptionCE.fs |
Updates task/value-option CE tests. |
tests/FsToolkit.ErrorHandling.Tests/TaskValueOption.fs |
Replaces task constructor usages. |
tests/FsToolkit.ErrorHandling.Tests/TaskValidationCE.fs |
Updates validation CE tests. |
tests/FsToolkit.ErrorHandling.Tests/TaskValidation.fs |
Updates task constructors. |
tests/FsToolkit.ErrorHandling.Tests/TaskResultOption.fs |
Updates result-option constructors. |
tests/FsToolkit.ErrorHandling.Tests/TaskResultCE.fs |
Updates result CE tests. |
tests/FsToolkit.ErrorHandling.Tests/TaskResult.fs |
Updates catch-related tests. |
tests/FsToolkit.ErrorHandling.Tests/TaskOptionCE.fs |
Updates option CE tests. |
tests/FsToolkit.ErrorHandling.Tests/TaskOption.fs |
Updates option constructors. |
tests/FsToolkit.ErrorHandling.Tests/Result.fs |
Updates defaulting tests. |
tests/FsToolkit.ErrorHandling.Tests/ParallelAsyncValidationCE.fs |
Updates async constructors. |
tests/FsToolkit.ErrorHandling.Tests/ParallelAsyncResultCE.fs |
Updates async constructors. |
tests/FsToolkit.ErrorHandling.Tests/Option.fs |
Updates async/task constructors. |
tests/FsToolkit.ErrorHandling.Tests/FsToolkit.ErrorHandling.Tests.fsproj |
Adds .NET 10 testing. |
tests/FsToolkit.ErrorHandling.Tests/BackgroundTaskValueOptionCE.fs |
Updates background-task CE tests. |
tests/FsToolkit.ErrorHandling.Tests/BackgroundTaskResultCE.fs |
Updates background-task result tests. |
tests/FsToolkit.ErrorHandling.Tests/BackgroundTaskOptionCE.fs |
Updates background-task option tests. |
tests/FsToolkit.ErrorHandling.Tests/AsyncValidation.fs |
Updates async validation constructors. |
tests/FsToolkit.ErrorHandling.Tests/AsyncResultOptionCE.fs |
Updates result-option constructors. |
tests/FsToolkit.ErrorHandling.Tests/AsyncResultCE.fs |
Updates async result tests. |
tests/FsToolkit.ErrorHandling.Tests/AsyncResult.fs |
Updates catch tests. |
tests/FsToolkit.ErrorHandling.Tests/AsyncOptionCE.fs |
Updates async option CE tests. |
tests/FsToolkit.ErrorHandling.Tests/AsyncOption.fs |
Updates async constructors. |
tests/FsToolkit.ErrorHandling.JobResult.Tests/JobResultOption.fs |
Updates JobResult option constructors. |
tests/FsToolkit.ErrorHandling.JobResult.Tests/JobResultCE.fs |
Updates JobResult CE tests. |
tests/FsToolkit.ErrorHandling.JobResult.Tests/JobResult.fs |
Updates JobResult APIs in tests. |
tests/FsToolkit.ErrorHandling.JobResult.Tests/JobOptionCE.fs |
Updates JobOption CE tests. |
tests/FsToolkit.ErrorHandling.JobResult.Tests/JobOption.fs |
Updates JobOption tests. |
tests/FsToolkit.ErrorHandling.JobResult.Tests/FsToolkit.ErrorHandling.JobResult.Tests.fsproj |
Adds .NET 10 testing. Moderate finding (1 vote): the .NET 10 leg resolves a library whose targets stop at .NET 9. |
tests/FsToolkit.ErrorHandling.IcedTasks.Tests/ValueTaskValueOptionCE.fs |
Updates value-task CE tests. |
tests/FsToolkit.ErrorHandling.IcedTasks.Tests/FsToolkit.ErrorHandling.IcedTasks.Tests.fsproj |
Adds targets and warning configuration. Critical finding (1 vote): retain FS3511 in NoWarn; moderate finding (1 vote): the .NET 10 leg resolves a library whose targets stop at .NET 9. |
tests/FsToolkit.ErrorHandling.IcedTasks.Tests/CancellableTaskValidationCE.fs |
Updates cancellable-task validation constructors. |
tests/FsToolkit.ErrorHandling.IcedTasks.Tests/CancellableTaskResultCE.fs |
Updates cancellable-task result constructors. |
tests/FsToolkit.ErrorHandling.AsyncSeq.Tests/FsToolkit.ErrorHandling.AsyncSeq.Tests.fsproj |
Adds .NET 10 testing. Moderate finding (1 vote): the .NET 10 leg resolves a library whose targets stop at .NET 9. |
tests/Directory.Build.props |
Selects FSharp.Core versions by target framework. |
src/FsToolkit.ErrorHandling/TaskValueOption.fs |
Uses Task.result. |
src/FsToolkit.ErrorHandling/TaskValidationCE.fs |
Uses Task.result. |
src/FsToolkit.ErrorHandling/TaskValidation.fs |
Uses Task.result. |
src/FsToolkit.ErrorHandling/TaskResultOption.fs |
Adds some and compatibility support. |
src/FsToolkit.ErrorHandling/TaskResultCE.fs |
Uses Task.result. |
src/FsToolkit.ErrorHandling/TaskResult.fs |
Adds catchWith and updates task handling. |
src/FsToolkit.ErrorHandling/TaskOption.fs |
Uses Task.result. |
src/FsToolkit.ErrorHandling/Task.FSharpCore11.fs |
Adds older-target Task shims. Critical finding (1 vote): backgroundTask is unavailable on the older FSharp.Core baseline. Critical finding (1 vote): the NET_10_0_OR_GREATER guard is misspelled and includes compatibility implementations in the .NET 10 build. |
src/FsToolkit.ErrorHandling/Task.fs |
Removes or shims overlapping Task APIs. Critical finding (1 vote): the misspelled target guard leaves obsolete Task.singleton enabled on .NET 10. |
src/FsToolkit.ErrorHandling/ResultOptionCE.fs |
Uses ResultOption.some. |
src/FsToolkit.ErrorHandling/ResultOption.fs |
Adds some and compatibility support. |
src/FsToolkit.ErrorHandling/Result.fs |
Conditionally removes overlapping FSharp.Core APIs. Critical finding (1 vote): unqualified map and mapError calls can fail the .NET 10 build, including the occurrence at line 504. Nit (1 vote): the retained valueOr documentation links to removed documentation. Critical finding (1 vote): the misspelled target guard leaves local helpers defined on .NET 10. |
src/FsToolkit.ErrorHandling/ParallelAsyncValidationCE.fs |
Uses Async.result. |
src/FsToolkit.ErrorHandling/ParallelAsyncResultCE.fs |
Uses Async.result. |
src/FsToolkit.ErrorHandling/List.fs |
Uses Async.result. |
src/FsToolkit.ErrorHandling/FsToolkit.ErrorHandling.fsproj |
Adds .NET 10 and shim files. |
src/FsToolkit.ErrorHandling/AsyncValidationCE.fs |
Uses Async.result. |
src/FsToolkit.ErrorHandling/AsyncValidation.fs |
Uses Async.result. |
src/FsToolkit.ErrorHandling/AsyncResultOptionCE.fs |
Uses Async.result and some. |
src/FsToolkit.ErrorHandling/AsyncResultOption.fs |
Adds some and compatibility support. |
src/FsToolkit.ErrorHandling/AsyncResultCE.fs |
Uses Async.result. |
src/FsToolkit.ErrorHandling/AsyncResult.fs |
Adds catchWith and updates async handling. |
src/FsToolkit.ErrorHandling/AsyncOptionCE.fs |
Uses Async.result. |
src/FsToolkit.ErrorHandling/AsyncOption.fs |
Uses Async.result. |
src/FsToolkit.ErrorHandling/Async.FSharpCore11.fs |
Adds older-target Async shims. Critical finding (3 votes): cancellation exceptions are caught instead of rethrown at lines 106 and 130. Critical finding (1 vote): the misspelled target guard includes the shim in the .NET 10 build. Nits (1 vote each): the module summary describes Task computations, and the example uses unavailable Async.RunSynchronouslyImmediate. |
src/FsToolkit.ErrorHandling/Async.fs |
Removes or shims overlapping Async APIs. Critical finding (1 vote): the misspelled target guard leaves obsolete Async.singleton enabled on .NET 10. |
src/FsToolkit.ErrorHandling.JobResult/List.fs |
Uses renamed JobResult APIs. |
src/FsToolkit.ErrorHandling.JobResult/JobResultOptionCE.fs |
Uses some. |
src/FsToolkit.ErrorHandling.JobResult/JobResultOption.fs |
Adds some and compatibility support. |
src/FsToolkit.ErrorHandling.JobResult/JobResult.fs |
Adds ok and catchWith. |
src/FsToolkit.ErrorHandling.JobResult/JobOptionCE.fs |
Uses Job.result. |
src/FsToolkit.ErrorHandling.JobResult/JobOption.fs |
Adds some and none. |
src/FsToolkit.ErrorHandling.JobResult/Job.fs |
Uses Job.result. |
src/FsToolkit.ErrorHandling.IcedTasks/CancellableValueTaskResultCE.fs |
Adds ok and compatibility support. |
src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskValidationCE.fs |
Adds ok and updates lifting. |
src/FsToolkit.ErrorHandling.IcedTasks/CancellableTaskResultCE.fs |
Adds ok and compatibility support. |
src/Directory.Build.props |
Adds FSharp.Core 11 and asset configuration. |
RELEASE_NOTES.md |
Documents .NET 10 API changes. |
playground.fsx |
Updates API examples. |
gitbook/taskValueOption/zip.md |
Updates task constructor examples. |
gitbook/taskValueOption/map.md |
Updates task constructor examples. |
gitbook/taskValueOption/bind.md |
Updates task constructor examples. |
gitbook/taskValueOption/apply.md |
Updates task constructor examples. |
gitbook/taskResult/ofTask.md |
Updates exception-handling documentation. Nit (2 votes): the link should point to catchWith.md, not the incorrect catch API/page. |
gitbook/taskResult/ofCatchTask.md |
Removes obsolete documentation. |
gitbook/taskResult/catchWith.md |
Adds catchWith documentation. Nit (1 vote): the page is not listed in SUMMARY.md. |
gitbook/taskResult/catch.md |
Documents catch behavior. Moderate finding (1 vote): the signature and examples describe a call that does not match the API. |
gitbook/taskOption/zip.md |
Updates option examples. Moderate finding (3 votes): TaskOption.some None produces an outer Some, not the documented None. |
gitbook/taskOption/map.md |
Updates task examples. |
gitbook/taskOption/bind.md |
Updates task examples. |
gitbook/taskOption/apply.md |
Updates task examples. |
gitbook/task/zip.md |
Updates task examples. |
gitbook/task/map.md |
Updates task examples. |
gitbook/task/catch.md |
Removes obsolete documentation. Nit (1 vote): SUMMARY.md still links to this deleted page. |
gitbook/task/apply.md |
Updates task examples. |
gitbook/SUMMARY.md |
Updates documentation navigation. Nit (2 votes): the TaskResult entry links to catch.md instead of the new catchWith.md. |
gitbook/result/others.md |
Removes valueOr documentation. |
gitbook/option/sequenceTask.md |
Updates task examples. |
gitbook/option/sequenceAsync.md |
Updates async examples. |
gitbook/list/sequenceJobResultM.md |
Updates JobResult examples. |
gitbook/list/sequenceJobResultA.md |
Updates JobResult examples. |
gitbook/jobResultOption/map.md |
Updates JobResult examples. |
gitbook/jobResult/zipError.md |
Updates JobResult examples. |
gitbook/jobResult/zip.md |
Updates JobResult examples. |
gitbook/jobResult/ofResult.md |
Removes obsolete documentation. Nit (1 vote): SUMMARY.md still points to the deleted page. |
gitbook/jobResult/catchWith.md |
Updates catchWith examples. Nit (1 vote): SUMMARY.md points to the missing catch.md. |
gitbook/jobOption/map.md |
Updates Job examples. |
gitbook/jobOption/either.md |
Updates Job examples. Moderate finding (2 votes): the example has an extra closing parenthesis and does not parse. |
gitbook/jobOption/apply.md |
Updates Job examples. |
gitbook/job/zip.md |
Updates Job examples. |
gitbook/job/result.md |
Renames Job documentation. |
gitbook/job/apply.md |
Updates Job examples. |
gitbook/cancellableValueTaskResult/zip.md |
Updates result examples. |
gitbook/cancellableValueTaskResult/map.md |
Updates result examples. |
gitbook/cancellableValueTaskResult/apply.md |
Updates result examples. |
gitbook/cancellableValueTaskOption/zip.md |
Updates option examples. |
gitbook/cancellableValueTaskOption/map.md |
Updates option examples. |
gitbook/cancellableValueTaskOption/either.md |
Updates option examples. |
gitbook/cancellableValueTaskOption/bind.md |
Updates option examples. |
gitbook/cancellableValueTaskOption/apply.md |
Updates option examples. |
gitbook/cancellableTaskValidation/orElse.md |
Updates validation examples. |
gitbook/cancellableTaskValidation/ok.md |
Renames validation documentation. |
gitbook/cancellableTaskResult/ok.md |
Renames result documentation. |
gitbook/cancellableTaskOption/zip.md |
Updates cancellable-task examples. Moderate finding (3 votes): CancellableTaskOption.result is not defined and the example does not compile. |
gitbook/cancellableTaskOption/map.md |
Updates cancellable-task examples. |
gitbook/cancellableTaskOption/bind.md |
Updates cancellable-task examples. |
gitbook/cancellableTaskOption/apply.md |
Updates cancellable-task examples. |
gitbook/asyncResult/catchWith.md |
Updates catchWith examples. Nit (1 vote): SUMMARY.md still links to the missing catch.md. |
gitbook/asyncOption/orElseFunctions.md |
Updates Async option examples. |
gitbook/asyncOption/map.md |
Updates Async option examples. |
gitbook/asyncOption/bind.md |
Updates Async option examples. |
gitbook/asyncOption/apply.md |
Updates Async option examples. |
Directory.Build.props |
Updates language and nullable settings. |
build/DotEnv.fs |
Applies formatting updates. |
build/build.fs |
Updates build scripts. |
benchmarks/Benchmarks.fs |
Updates benchmark constructors. |
benchmarks/AsyncResultCE.fs |
Updates benchmark Async usage. |
Review details
Suppressed comments (14)
gitbook/asyncResult/catchWith.md:1
- This new page is named
catchWith, butgitbook/SUMMARY.mdstill links the AsyncResult entry to the missingasyncResult/catch.md. Update the summary entry so the documented API is reachable.
gitbook/jobResult/catchWith.md:1 - This new page is named
catchWith, butgitbook/SUMMARY.mdstill links the JobResult entry to the missingjobResult/catch.md. Update the summary entry so the documented API is reachable.
gitbook/jobResult/ofResult.md:1 - Deleting this page leaves
gitbook/SUMMARY.mdpointing atjobResult/ofResult.md, which makes the published documentation navigation link dead. Update the summary to remove the entry or point it at the replacement page.
gitbook/task/catch.md:1 - Deleting this page leaves
gitbook/SUMMARY.mdpointing attask/catch.md, which makes the published documentation navigation link dead. Update the summary to remove the entry or point it at the replacement API page.
gitbook/taskResult/catch.md:12 - The new signature and examples do not match the API:
TaskResult.catchis the obsolete two-argument mapper alias in the source, while the one-argumentTask<'T> -> Task<Result<'T, exn>>function isTask.catch; custom error mapping isTaskResult.catchWith. This page therefore documents a call that will not compile.
gitbook/taskResult/catchWith.md:1 - This
catchWithpage is not listed ingitbook/SUMMARY.md; the TaskResult navigation only exposescatch.md. Add the new page to the summary so users can discover the API.
src/FsToolkit.ErrorHandling/Async.FSharpCore11.fs:131 - This separate catch-all has the same cancellation bug even if
catchWithis corrected: a canceled computation is converted toErrorinstead of remaining canceled. Delegate through the cancellation-preservingcatchWithafter mapping success toOk.
src/FsToolkit.ErrorHandling/Async.FSharpCore11.fs:11 - The module summary describes
Taskcomputations, but this file defines theAsyncshims. This makes the generated API documentation misleading; describe asynchronous computations instead.
src/FsToolkit.ErrorHandling/Async.FSharpCore11.fs:24 - The shim is compiled for pre-net10 targets, but this example invokes
Async.RunSynchronouslyImmediate, which is a newer FSharp.Core API and is not provided by this shim. The copied examples therefore do not work for the targets this file supports; use the broadly availableAsync.RunSynchronouslythroughout the shim documentation.
src/FsToolkit.ErrorHandling/Result.fs:504 - This net10 guard removes
defaultValue, whileignoreErrorstill callsdefaultValueunqualified at line 558. That leaves the net10 source with an unresolved binding; useResult.defaultValueor keep a local compatibility definition.
src/FsToolkit.ErrorHandling/Result.fs:678 - The XML documentation for the retained pre-net10
valueOrfunction still links toresult/others#valueor, but this PR removes that section fromgitbook/result/others.md. The generated API docs will contain a dead link; update the link to the replacementdefaultWithdocumentation or remove it.
tests/FsToolkit.ErrorHandling.AsyncSeq.Tests/FsToolkit.ErrorHandling.AsyncSeq.Tests.fsproj:5 - This test project now has a
net10.0leg, but its project reference points to a library whoseTargetFrameworksstop atnet9.0. The net10 test therefore resolves the net9 source asset and does not validate the AsyncSeq package under the intended FSharp.Core 11/net10 target; add a matching net10 library target or remove this misleading test leg.
tests/FsToolkit.ErrorHandling.IcedTasks.Tests/FsToolkit.ErrorHandling.IcedTasks.Tests.fsproj:5 - This test project now has a
net10.0leg, but its project reference points to a library whoseTargetFrameworksstop atnet9.0. The net10 test therefore resolves the net9 source asset and does not validate the IcedTasks package under the intended FSharp.Core 11/net10 target; add a matching net10 library target or remove this misleading test leg.
tests/FsToolkit.ErrorHandling.JobResult.Tests/FsToolkit.ErrorHandling.JobResult.Tests.fsproj:5 - This test project now has a
net10.0leg, but its project reference points to a library whoseTargetFrameworksstop atnet9.0. The net10 test therefore resolves the net9 source asset and does not validate the dependent package under the intended FSharp.Core 11/net10 target; add a matching net10 library target or remove this misleading test leg.
- Files reviewed: 132/132 changed files
- Comments generated: 14
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| @@ -0,0 +1,195 @@ | |||
| // NOTE Direct copy of FSharp.Core V11 with the following alterations: | |||
| // - namespace is FsToolkit.ErrorHandling instead of Microsoft.FSharp.Control | |||
| #if !NET_10_0_OR_GREATER | |||
| let catchWith (handler: exn -> 'T) (computation: Async<'T>) : Async<'T> = | ||
| async { | ||
| try | ||
| return! computation | ||
| with e -> | ||
| return handler e | ||
| } |
| [<RequireQualifiedAccess>] | ||
| module Async = | ||
|
|
||
| #if !NET_10_0_OR_GREATER |
| [<RequireQualifiedAccess>] | ||
| module Result = | ||
|
|
||
| #if !NET_10_0_OR_GREATER |
| [<RequireQualifiedAccess>] | ||
| module Result = | ||
|
|
||
| #if !NET_10_0_OR_GREATER |
| ```fsharp | ||
| let left = CancellableTaskOption.some 123 | ||
| let right = CancellableTaskOption.singleton None | ||
| let right = CancellableTaskOption.result None |
| |> JobOption.either | ||
| (fun user -> Job.singleton (sprintf "Found user: %s" user.Name)) | ||
| (Job.singleton "User not found") | ||
| (fun user -> Job.result $"Found user: {user.Name}")) |
| ```fsharp | ||
| let left = TaskOption.some 123 | ||
| let right = TaskOption.singleton None | ||
| let right = TaskOption.some None |
| * Transforms | ||
| * [ofAsync](taskResult/ofAsync.md) | ||
| * [ofCatchTask](taskResult/ofCatchTask.md) | ||
| * [catch](taskResult/catch.md) |
| Transforms a `Task<'T>` into a `Task<Result<'T, exn>>` by wrapping the value in `Ok`. | ||
|
|
||
| > **Note:** This function does **not** catch exceptions thrown by the task. Any exceptions will propagate as-is. To catch exceptions and map them to the `Error` case, use [`ofCatchTask`](ofCatchTask.md). | ||
| > **Note:** This function does **not** catch exceptions thrown by the task. Any exceptions will propagate as-is. To catch exceptions and map them to the `Error` case, use [`catch`](catch.md). |
I think that we should consider going to |
That was my initial instinct; I only changed tack due to it being a preview SDK and the CI not being rigged for it as yet. Definitely don't want to release a non-beta release depending on FSharp.Core 11-rc That said, non-LTS TFM-specific builds have less value for me and should be candidates for trimming (leave net6.0 etc, but remove net9.0, and maybe run the tests under net8.0 (to cover the net8.0 TFM build)). I'd venture running tests under net9.0 should also removed, i.e. maybe replace the existing net9.0 stuff with net10.0 as part of this release cycle then we pin its API surface via Package Validation (e.g. https://github.com/jet/equinox/blob/master/src/Equinox/Equinox.fsproj#L5). So maybe:
|
be58ca2 to
1a49f69
Compare
# Conflicts: # RELEASE_NOTES.md
9f0d57d to
14494d8
Compare
14494d8 to
0d267a4
Compare
includes transition to Async.StartTaskImmediate added net10.0 TFMs and coverage
0d267a4 to
3616965
Compare
2265c31 to
6caa072
Compare
|
@TheAngryByrd This one goes after #376 - no point reviewing while the diffs combine both. Will rebase once you merge the other. I have no plans to implement anything else in the context of this API (though maybe |
FSharp.Core adds utility functions for Async, Task, ValueTask as covered in fsharp/fslang-suggestions#1466 and fsharp/fslang-suggestions#1467 that overlap significantly / borrow from FsToolkit.Error Handling.
In the short term, there are some signature clashes (Task.catch in FSharp.Core 11 returns Result, not Choice)
In the medium term, this repo won't yet adopt SDK 11, and the net9.0 and earlier builds won't have access to the new Async.Await.
In the long term that stuff gets removed from here and removed from the docs
Thus this PR:
NOTE The FSharp.Core shims re Async and Task match the behavior (pass the test suite) and surface area with the following deviations:
Async.Await doesnot fully replicated the nested stack trace preservation behavior that FSharp.Core v7 provides (top level stack trace is shown, but the full trace during a trampolined nested call can only be provided by the real implementation). (Obviously it does the unwrapping demanded by Task to AsyncResult transition wrapsExceptioninto theAggregateException#154 etc)Async.AwaitasAsync.Await<_>to exclude a clash withAsync.Await<_, _, _) which does not present with the real FSharp.Core's API surface).Resolves #372
Resolves #154
Resolves #361