Skip to content

Commit 6afd93b

Browse files
Add Task/AsyncOption defaultValue and defaultWith (#238)
* Add Task/AsyncOption defaultValue and defaultWith * Add doc comments
1 parent 4b254bf commit 6afd93b

File tree

4 files changed

+146
-0
lines changed

4 files changed

+146
-0
lines changed

src/FsToolkit.ErrorHandling.TaskResult/TaskOption.fs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,30 @@ module TaskOption =
5353
| Some v -> onSome v
5454
| None -> onNone ()
5555
)
56+
57+
/// <summary>
58+
/// Gets the value of the option if the option is <c>Some</c>, otherwise returns the specified default value.
59+
/// </summary>
60+
/// <param name="value">The specified default value.</param>
61+
/// <param name="asyncOption">The input option.</param>
62+
/// <returns>
63+
/// The option if the option is <c>Some</c>, else the default value.
64+
/// </returns>
65+
let inline defaultValue (value: 'value) (taskOption: Task<'value option>) =
66+
taskOption
67+
|> Task.map (Option.defaultValue value)
68+
69+
/// <summary>
70+
/// Gets the value of the option if the option is <c>Some</c>, otherwise evaluates <paramref name="defThunk"/> and returns the result.
71+
/// </summary>
72+
/// <param name="defThunk">A thunk that provides a default value when evaluated.</param>
73+
/// <param name="asyncOption">The input option.</param>
74+
/// <returns>
75+
/// The option if the option is <c>Some</c>, else the result of evaluating <paramref name="defThunk"/>.
76+
/// </returns>
77+
let inline defaultWith
78+
([<InlineIfLambda>] defThunk: unit -> 'value)
79+
(taskOption: Task<'value option>)
80+
: Task<'value> =
81+
taskOption
82+
|> Task.map (Option.defaultWith defThunk)

src/FsToolkit.ErrorHandling/AsyncOption.fs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,30 @@ module AsyncOption =
5252
| Some v -> onSome v
5353
| None -> onNone
5454
)
55+
56+
/// <summary>
57+
/// Gets the value of the option if the option is <c>Some</c>, otherwise returns the specified default value.
58+
/// </summary>
59+
/// <param name="value">The specified default value.</param>
60+
/// <param name="asyncOption">The input option.</param>
61+
/// <returns>
62+
/// The option if the option is <c>Some</c>, else the default value.
63+
/// </returns>
64+
let inline defaultValue (value: 'value) (asyncOption: Async<'value option>) =
65+
asyncOption
66+
|> Async.map (Option.defaultValue value)
67+
68+
/// <summary>
69+
/// Gets the value of the option if the option is <c>Some</c>, otherwise evaluates <paramref name="defThunk"/> and returns the result.
70+
/// </summary>
71+
/// <param name="defThunk">A thunk that provides a default value when evaluated.</param>
72+
/// <param name="asyncOption">The input option.</param>
73+
/// <returns>
74+
/// The option if the option is <c>Some</c>, else the result of evaluating <paramref name="defThunk"/>.
75+
/// </returns>
76+
let inline defaultWith
77+
([<InlineIfLambda>] defThunk: unit -> 'value)
78+
(asyncOption: Async<'value option>)
79+
: Async<'value> =
80+
asyncOption
81+
|> Async.map (Option.defaultWith defThunk)

tests/FsToolkit.ErrorHandling.TaskResult.Tests/TaskOption.fs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,52 @@ let eitherTests =
154154
}
155155
]
156156

157+
let defaultValueTests =
158+
testList "TaskOption.defaultValue Tests" [
159+
testCaseTask "Some"
160+
<| fun () ->
161+
task {
162+
let defaultValue = 10
163+
let expectedValue = 5
164+
165+
let taskOption = TaskOption.retn expectedValue
166+
let! result = TaskOption.defaultValue defaultValue taskOption
167+
Expect.equal result expectedValue ""
168+
}
169+
170+
testCaseTask "None"
171+
<| fun () ->
172+
task {
173+
let expectedValue = 10
174+
let taskOption = Task.singleton None
175+
let! result = TaskOption.defaultValue expectedValue taskOption
176+
Expect.equal result expectedValue ""
177+
}
178+
]
179+
180+
let defaultWithTests =
181+
testList "TaskOption.defaultWith Tests" [
182+
testCaseTask "Some"
183+
<| fun () ->
184+
task {
185+
let defaultValue = 10
186+
let expectedValue = 5
187+
188+
let taskOption = TaskOption.retn expectedValue
189+
let! result = TaskOption.defaultWith (fun () -> defaultValue) taskOption
190+
Expect.equal result expectedValue ""
191+
}
192+
193+
testCaseTask "None"
194+
<| fun () ->
195+
task {
196+
let expectedValue = 10
197+
let taskOption = Task.singleton None
198+
let! result = TaskOption.defaultWith (fun () -> expectedValue) taskOption
199+
Expect.equal result expectedValue ""
200+
}
201+
]
202+
157203
let allTests =
158204
testList "Task Option Tests" [
159205
mapTests
@@ -162,4 +208,6 @@ let allTests =
162208
retnTests
163209
taskOptionOperatorTests
164210
eitherTests
211+
defaultValueTests
212+
defaultWithTests
165213
]

tests/FsToolkit.ErrorHandling.Tests/AsyncOption.fs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,48 @@ let eitherTests =
127127
}
128128
]
129129

130+
let defaultValueTests =
131+
testList "TaskOption.defaultValue Tests" [
132+
testCaseAsync "Some"
133+
<| async {
134+
let defaultValue = 10
135+
let expectedValue = 5
136+
137+
let asyncOption = AsyncOption.retn expectedValue
138+
let! result = AsyncOption.defaultValue defaultValue asyncOption
139+
Expect.equal result expectedValue ""
140+
}
141+
142+
testCaseAsync "None"
143+
<| async {
144+
let expectedValue = 10
145+
let asyncOption = Async.singleton None
146+
let! result = AsyncOption.defaultValue expectedValue asyncOption
147+
Expect.equal result expectedValue ""
148+
}
149+
]
150+
151+
let defaultWithTests =
152+
testList "AsyncOption.defaultWith Tests" [
153+
testCaseAsync "Some"
154+
<| async {
155+
let defaultValue = 10
156+
let expectedValue = 5
157+
158+
let asyncOption = AsyncOption.retn expectedValue
159+
let! result = AsyncOption.defaultWith (fun () -> defaultValue) asyncOption
160+
Expect.equal result expectedValue ""
161+
}
162+
163+
testCaseAsync "None"
164+
<| async {
165+
let expectedValue = 10
166+
let asyncOption = Async.singleton None
167+
let! result = AsyncOption.defaultWith (fun () -> expectedValue) asyncOption
168+
Expect.equal result expectedValue ""
169+
}
170+
]
171+
130172
let allTests =
131173
testList "Async Option Tests" [
132174
mapTests
@@ -135,4 +177,6 @@ let allTests =
135177
retnTests
136178
asyncOptionOperatorTests
137179
eitherTests
180+
defaultValueTests
181+
defaultWithTests
138182
]

0 commit comments

Comments
 (0)