Skip to content

Commit f702e24

Browse files
committed
Many updates
1 parent eaf023c commit f702e24

File tree

14 files changed

+748
-436
lines changed

14 files changed

+748
-436
lines changed

RELEASE_NOTES.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
### 5.0.0-beta001
2+
- BREAKING: [Remove Ply and update to FSharp 6](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/248) Credits @TheAngryByrd
3+
- BREAKING: [Remove MergeSources (and!) from some implementations](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/261) Credits @TheAngryByrd
4+
- [Use Microsoft.Bcl.AsyncInterfaces in netstandard2.0 (Allows IAsyncDisposable and IAsyncEnumerable)](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/250) Credits @TheAngryByrd
5+
- [Build against Net8](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/251) Credits @TheAngryByrd
6+
- [Fix Overload Resolution to Align to Computation Expression used](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/252) Credits @TheAngryByrd
7+
- [refactor!: Seq.sequenceResultM returns Array instead of seq](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/255) Credits @bartelink
8+
- [feat(Seq): sequenceResultA](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/255) Credits @bartelink
19

2-
### 5.0.0-alpha.1
3-
- [refactor!: Seq.sequenceResultM returns Array instead of seq](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/255) [@bartelink](https://github.com/bartelink)
4-
- [feat(Seq): sequenceResultA](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/255) [@bartelink](https://github.com/bartelink)
510

611
### 4.18.0 - October 23, 2024
712
- [Add Array errorhandling](https://github.com/demystifyfp/FsToolkit.ErrorHandling/pull/279) Credits @DashieTM

benchmarks/benchmarks.fsproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project Sdk="Microsoft.NET.Sdk">
33
<PropertyGroup>
4-
<TargetFramework>net7.0</TargetFramework>
4+
<TargetFramework>net8.0</TargetFramework>
55
<OutputType>Exe</OutputType>
66
<LangVersion>preview</LangVersion>
77
</PropertyGroup>
@@ -31,4 +31,4 @@
3131
<ProjectReference Include="..\src\FsToolkit.ErrorHandling.JobResult\FsToolkit.ErrorHandling.JobResult.fsproj" />
3232
</ItemGroup>
3333
<Import Project="..\.paket\Paket.Restore.targets" />
34-
</Project>
34+
</Project>

build/build.fs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ let dotnetPack ctx =
348348
Configuration = configuration ctx.Context.AllExecutingTargets
349349
MSBuildParams =
350350
{
351-
MSBuild.CliArguments.Create() with
351+
p.MSBuildParams with
352352
// "/p" (property) arguments to MSBuild.exe
353353
Properties = [
354354
("Version", release.NugetVersion)
@@ -425,8 +425,8 @@ let initTargets () =
425425
BuildServer.install [ GitHubActions.Installer ]
426426

427427
Option.iter (TraceSecrets.register "<GITHUB_TOKEN>") githubToken.Value
428-
Option.iter (TraceSecrets.register "<NUGET_TOKEN>") githubToken.Value
429-
Option.iter (TraceSecrets.register "<FSTK_NUGET_TOKEN>") githubToken.Value
428+
Option.iter (TraceSecrets.register "<NUGET_TOKEN>") nugetToken.Value
429+
Option.iter (TraceSecrets.register "<FSTK_NUGET_TOKEN>") nugetToken.Value
430430

431431

432432
Target.create "Clean" clean

paket.dependencies

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ nuget FSharp.Core >= 6.0.1
77
nuget Hopac >= 0.5.1
88
nuget FSharp.Control.AsyncSeq >= 3.2.1
99
nuget Fable.Core >= 4.2.0
10-
nuget IcedTasks >= 0.11.0
10+
nuget IcedTasks >= 0.11.4
1111
nuget Microsoft.SourceLink.GitHub prerelease copy_local: true
1212
nuget Microsoft.Bcl.AsyncInterfaces >= 6.0.0 framework:netstandard2.0
1313

paket.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ NUGET
1010
FSharp.Core (6.0.1)
1111
Hopac (0.5.1)
1212
FSharp.Core (>= 4.5.2) - restriction: >= netstandard2.0
13-
IcedTasks (0.11)
13+
IcedTasks (0.11.4)
1414
FSharp.Core (>= 6.0.1) - restriction: >= netstandard2.0
1515
Microsoft.Bcl.AsyncInterfaces (>= 6.0) - restriction: && (>= netstandard2.0) (< netstandard2.1)
1616
Microsoft.Bcl.AsyncInterfaces (6.0) - restriction: == netstandard2.0

playground.fsx

Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
#r "nuget: FsToolkit.ErrorHandling.TaskResult"
2+
3+
let inline id x = x
4+
5+
open FsToolkit.ErrorHandling
6+
7+
Result.ofChoice
8+
module Operators =
9+
10+
let inline bindM builder m ([<InlineIfLambda>] f) =
11+
(^M: (member Bind: 'd -> ('e -> 'c) -> 'c) (builder, m, f))
12+
13+
let inline bind2M builder m1 m2 f =
14+
(^M: (member Bind2: 'a -> 'b -> ('e * 'f -> 'c) -> 'c) (builder, m1, m2, f))
15+
16+
let inline delayM builder x =
17+
(^M: (member Delay: (unit -> 'a) -> 'c) (builder, x))
18+
19+
/// Inject a value into the monadic type
20+
let inline returnM builder x =
21+
(^M: (member Return: 'b -> 'c) (builder, x))
22+
23+
let inline returnFromM builder x =
24+
(^M: (member ReturnFrom: 'b -> 'c) (builder, x))
25+
26+
let inline bindReturnM builder m ([<InlineIfLambda>] f) =
27+
(^M: (member BindReturn: 'd -> ('e -> 'c) -> 'f) (builder, m, f))
28+
29+
let inline bind2ReturnM builder m1 m2 ([<InlineIfLambda>] f) =
30+
(^M: (member Bind2Return: 'a -> 'b -> ('c * 'd -> 'e) -> 'f) (builder, m1, m2, f))
31+
32+
let inline mergeSourcesM builder m1 m2 =
33+
(^M: (member MergeSources: 'a * 'b -> 'c) (builder, m1, m2))
34+
35+
let inline mergeSources3M builder m1 m2 m3 =
36+
(^M: (member MergeSources3: 'a * 'b * 'c -> 'd) (builder, m1, m2, m3))
37+
38+
let inline liftM builder m ([<InlineIfLambda>] f) =
39+
bindM builder m
40+
<| fun m1 -> returnM builder (f m1)
41+
42+
let inline lift2M builder1 builder2 m1 m2 ([<InlineIfLambda>] f) =
43+
bindM builder1 m1
44+
<| fun m1' ->
45+
liftM builder2 m2
46+
<| fun m2' -> (f m1' m2')
47+
48+
/// Sequential application
49+
let inline applyM (builder1: ^M1) (builder2: ^M2) f m =
50+
lift2M builder1 builder2 f m
51+
<| fun f x -> f x
52+
53+
/// Sequential application
54+
let inline zipM (builder1: ^M1) (builder2: ^M2) m1 m2 =
55+
lift2M builder1 builder2 m1 m2
56+
<| fun m1' m2' -> (m1', m2')
57+
58+
59+
module Async =
60+
let inline bind ([<InlineIfLambda>] f) x = Operators.bindM async x f
61+
let inline delay x = Operators.delayM async x
62+
let inline singleton x = Operators.returnM async x
63+
let inline returnFrom x = Operators.returnFromM async x
64+
let inline bindReturn ([<InlineIfLambda>] f) x = Operators.liftM async x f
65+
let inline map ([<InlineIfLambda>] f) x = bindReturn f x
66+
let inline mergeSources x y = Operators.zipM async async x y
67+
let inline zip x y = mergeSources x y
68+
let inline apply f x = Operators.applyM async async f x
69+
70+
let inline flatten x = bind id x
71+
72+
module Result =
73+
open FsToolkit.ErrorHandling
74+
75+
let inline either ([<InlineIfLambda>] okF) ([<InlineIfLambda>] errorF) =
76+
function
77+
| Ok x -> okF x
78+
| Error e -> errorF e
79+
80+
let inline bind ([<InlineIfLambda>] f) x = Operators.bindM result x f
81+
let inline delay x = Operators.delayM result x
82+
let inline singleton x = Operators.returnM result x
83+
let inline returnFrom x = Operators.returnFromM result x
84+
let inline bindReturn ([<InlineIfLambda>] f) x = Operators.bindReturnM result x f
85+
let inline map ([<InlineIfLambda>] f) x = bindReturn f x
86+
let inline mergeSources x y = Operators.mergeSourcesM result x y
87+
let inline zip x y = mergeSources x y
88+
89+
let inline apply f x =
90+
mergeSources f x
91+
|> bindReturn (fun (f', x') -> f' x')
92+
93+
let inline sequence builder f x =
94+
x
95+
|> either
96+
(fun x -> Operators.bindReturnM builder x f)
97+
(fun x ->
98+
x
99+
|> Result.Error
100+
|> Operators.returnM builder
101+
)
102+
103+
let inline sequenceLift builder f x =
104+
x
105+
|> either
106+
(fun x -> Operators.liftM builder x f)
107+
(fun x ->
108+
x
109+
|> Result.Error
110+
|> Operators.returnM builder
111+
)
112+
113+
let inline sequenceAsync x = sequenceLift async Ok x
114+
115+
let inline sequenceAsyncResult x = sequenceLift async id x
116+
117+
let inline flatten x = bind id x
118+
119+
module AsyncResult =
120+
121+
type AsyncResultBuilder() =
122+
member inline _.Return x = Async.singleton (Result.singleton x)
123+
124+
member inline _.Bind(m, f: 'a -> Async<Result<'b, 'c>>) =
125+
m
126+
|> Async.bind (fun x ->
127+
Result.map f x
128+
|> Result.sequenceAsyncResult
129+
)
130+
131+
member inline _.Source(x: Async<Result<'a, 'b>>) = x
132+
133+
[<AutoOpen>]
134+
module AsyncResultBuilderExt =
135+
open System.Threading.Tasks
136+
137+
type AsyncResultBuilder with
138+
139+
member inline _.Source(x: Async<'a>) = Async.map Ok x
140+
141+
member inline _.Source(x: Task<'a>) =
142+
task {
143+
let! x = x
144+
return Ok x
145+
}
146+
|> Async.AwaitTask
147+
148+
member inline _.Source(x: Result<_, _>) = Async.singleton x
149+
150+
let asyncResult = AsyncResultBuilder()
151+
152+
let inline bind ([<InlineIfLambda>] f) x = Operators.bindM asyncResult x f
153+
let inline singleton x = Operators.returnM asyncResult x
154+
155+
let example () =
156+
asyncResult {
157+
let! x = singleton 1
158+
let! y = singleton 2
159+
let! z = Async.singleton 3
160+
let! a = Result.singleton 4
161+
162+
return
163+
x
164+
+ y
165+
+ z
166+
+ a
167+
}
168+
169+
170+
171+
module DisposableOptionThings =
172+
open System
173+
open System.Threading.Tasks
174+
175+
[<RequireQualifiedAccess>]
176+
[<DefaultAugmentation(false)>]
177+
[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
178+
[<StructuralEquality; StructuralComparison>]
179+
type DisposableOption<'a when 'a :> IDisposable> =
180+
| None
181+
| Some of 'a
182+
interface IDisposable with
183+
member this.Dispose() =
184+
match this with
185+
| None -> ()
186+
| Some x -> x.Dispose()
187+
188+
static member inline OfObj<'a when 'a :> IDisposable> (x: 'a) =
189+
if box x |> isNull then None else Some x
190+
191+
static member inline ToOption(x: DisposableOption<'a>) =
192+
match x with
193+
| None -> Option.None
194+
| Some x -> Option.Some x
195+
196+
static member inline ToValueOption(x: DisposableOption<'a>) =
197+
match x with
198+
| None -> ValueOption.None
199+
| Some x -> ValueOption.Some x
200+
201+
static member inline OfOption (x: 'a Option) =
202+
match x with
203+
| Option.None -> None
204+
| Option.Some x -> Some x
205+
206+
static member inline OfValueOption (x: 'a ValueOption) =
207+
match x with
208+
| ValueNone -> None
209+
| ValueSome x -> Some x
210+
211+
static member inline op_Implicit (x: 'a) =
212+
DisposableOption.OfObj x
213+
214+
static member inline op_Implicit (x: 'a DisposableOption) =
215+
DisposableOption.ToOption x
216+
217+
static member inline op_Implicit (x: 'a DisposableOption) =
218+
DisposableOption.ToValueOption x
219+
220+
static member inline op_Implicit (x: 'a Option) =
221+
DisposableOption.OfOption x
222+
223+
static member inline op_Imp licit (x: 'a ValueOption) =
224+
DisposableOption.OfValueOption x
225+
226+
227+
[<RequireQualifiedAccess>]
228+
module DisposableOption =
229+
let inline bind f x =
230+
match x with
231+
| DisposableOption.Some x -> f x
232+
| DisposableOption.None -> None
233+
let inline map f x =
234+
match x with
235+
| DisposableOption.Some x -> Some (f x)
236+
| DisposableOption.None -> None
237+
let inline iter f x =
238+
match x with
239+
| DisposableOption.Some x -> f x
240+
| DisposableOption.None -> ()
241+
242+
243+
[<RequireQualifiedAccess>]
244+
type AsyncDisposableOption<'a when 'a :> IAsyncDisposable> =
245+
| Some of 'a
246+
| None
247+
interface IAsyncDisposable with
248+
member this.DisposeAsync() =
249+
match this with
250+
| Some x -> x.DisposeAsync()
251+
| None -> ValueTask()
252+
253+
static member inline ofObj (x: 'a) =
254+
if box x |> isNull then None else Some x
255+
256+
member inline x.toOption() =
257+
match x with
258+
| Some x -> Option.Some x
259+
| None -> Option.None
260+
261+
member inline x.toValueOption() =
262+
match x with
263+
| Some x -> ValueOption.Some x
264+
| None -> ValueOption.None
265+
266+
static member inline ofOption (x: 'a Option) =
267+
match x with
268+
| Option.Some x -> Some x
269+
| Option.None -> None
270+
271+
static member inline ofValueOption (x: 'a ValueOption) =
272+
match x with
273+
| ValueOption.ValueSome x -> Some x
274+
| ValueOption.ValueNone -> None
275+
276+
static member inline op_Implicit (x: 'a) =
277+
AsyncDisposableOption.ofObj x
278+
279+
static member inline op_Implicit (x: 'a AsyncDisposableOption) =
280+
x.toOption()
281+
282+
static member inline op_Implicit (x: 'a AsyncDisposableOption) =
283+
x.toValueOption()
284+
285+
static member inline op_Implicit (x: 'a Option) =
286+
AsyncDisposableOption.ofOption x
287+
288+
static member inline op_Implicit (x: 'a ValueOption) =
289+
AsyncDisposableOption.ofValueOption x
290+
291+
module Examples =
292+
open DisposableOptionThings
293+
open System.Diagnostics
294+
295+
let inline implicitConv (x: ^T) : ^U = ((^T or ^U) : (static member op_Implicit : ^T -> ^U) (x))
296+
let inline (!>) x = implicitConv x
297+
let inline (|!>) x f = f (!> x)
298+
299+
let activitySource = new ActivitySource("Playground.App")
300+
301+
let example () =
302+
use a = activitySource.StartActivity("lol") |> DisposableOption.OfObj
303+
a |!> Option.iter(fun a -> a.AddTag("hello", "world") |> ignore)
304+
()
305+

0 commit comments

Comments
 (0)