let iAmTask () : Task<int> = Task.FromResult(5)
let iAmValueTask () : ValueTask<int> = ValueTask.FromResult(5)
let iAmAsync () : Async<int> = async.Return 5
// Task expression works for all types
let example () = task {
let! boundTask = iAmTask()
let! boundValueTask = iAmValueTask()
let! async = iAmAsync()
return ()
}
// testTask errors on ValueTask and Async
let example () = testTask "I am Test" {
let! boundTask = iAmTask()
let! boundValueTask = iAmValueTask()
let! async = iAmAsync()
return ()
}
Potential Solution
I'm still trying to understand the TaskBuilder code in F#, but I think we could get away with inheriting from TaskBuilder and overloading Run. All of the TestTaskBuilder methods except for run are a direct forwarding to TaskBuilder. This would allow us to stay in sync with whatever the task expression supports.
If inheriting doesn't work, we could probably get close enough with a few additional Bind overloads.
The F#
task
expression can bind Tasks, ValueTasks, and Async types. It appearstestTask
currently only handles Task types.Example
Potential Solution
I'm still trying to understand the TaskBuilder code in F#, but I think we could get away with inheriting from TaskBuilder and overloading Run. All of the
TestTaskBuilder
methods except for run are a direct forwarding toTaskBuilder
. This would allow us to stay in sync with whatever the task expression supports.If inheriting doesn't work, we could probably get close enough with a few additional Bind overloads.