Skip to content

Commit

Permalink
Merge pull request #249 from bartelink/util-doc
Browse files Browse the repository at this point in the history
Utils naming/xmldoc polish
  • Loading branch information
abelbraaksma authored Apr 13, 2024
2 parents e76f921 + b4ce4ee commit f6ff7ab
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 43 deletions.
4 changes: 2 additions & 2 deletions src/FSharp.Control.TaskSeq/TaskSeq.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ type TaskSeq =
static member append: source1: TaskSeq<'T> -> source2: TaskSeq<'T> -> TaskSeq<'T>

/// <summary>
/// Concatenates a task sequence <paramref name="source1" /> with a non-async F# <see cref="seq" /> in <paramref name="source2" />
/// Concatenates a task sequence <paramref name="source1" /> with a (non-async) F# <see cref="seq" /> in <paramref name="source2" />
/// and returns a single task sequence.
/// </summary>
///
Expand All @@ -285,7 +285,7 @@ type TaskSeq =
static member appendSeq: source1: TaskSeq<'T> -> source2: seq<'T> -> TaskSeq<'T>

/// <summary>
/// Concatenates a non-async F# <see cref="seq" /> in <paramref name="source1" /> with a task sequence in <paramref name="source2" />
/// Concatenates a (non-async) F# <see cref="seq" /> in <paramref name="source1" /> with a task sequence in <paramref name="source2" />
/// and returns a single task sequence.
/// </summary>
///
Expand Down
4 changes: 2 additions & 2 deletions src/FSharp.Control.TaskSeq/TaskSeqBuilder.fs
Original file line number Diff line number Diff line change
Expand Up @@ -525,9 +525,9 @@ module LowPriority =
// and we need a way to distinguish these two methods.
//
// Types handled:
// - ValueTask (non-generic, because it implements GetResult() -> unit)
// - (non-generic) ValueTask (because it implements GetResult() -> unit)
// - ValueTask<'T> (because it implements GetResult() -> 'TResult)
// - Task (non-generic, because it implements GetResult() -> unit)
// - (non-generic) Task (because it implements GetResult() -> unit)
// - any other type that implements GetAwaiter()
//
// Not handled:
Expand Down
28 changes: 9 additions & 19 deletions src/FSharp.Control.TaskSeq/Utils.fs
Original file line number Diff line number Diff line change
@@ -1,46 +1,38 @@
namespace FSharp.Control

open System.Threading.Tasks
open System
open System.Diagnostics
open System.Threading
open System.Threading.Tasks

[<AutoOpen>]
module ValueTaskExtensions =
/// Extensions for ValueTask that are not available in NetStandard 2.1, but are
/// available in .NET 5+. We put them in Extension space to mimic the behavior of NetStandard 2.1
type ValueTask with

/// (Extension member) Gets a task that has already completed successfully.
static member inline CompletedTask =
// This mimics how it is done in .NET itself
// This mimics how it is done in net5.0 and later internally
Unchecked.defaultof<ValueTask>


module ValueTask =
let False = ValueTask<bool>()
let True = ValueTask<bool> true
let inline fromResult (value: 'T) = ValueTask<'T> value
let inline ofSource taskSource version = ValueTask<bool>(taskSource, version)
let inline ofTask (task: Task<'T>) = ValueTask<'T> task

let inline ignore (vtask: ValueTask<'T>) =
let inline ignore (valueTask: ValueTask<'T>) =
// this implementation follows Stephen Toub's advice, see:
// https://github.com/dotnet/runtime/issues/31503#issuecomment-554415966
if vtask.IsCompletedSuccessfully then
if valueTask.IsCompletedSuccessfully then
// ensure any side effect executes
vtask.Result |> ignore
valueTask.Result |> ignore
ValueTask()
else
ValueTask(vtask.AsTask())
ValueTask(valueTask.AsTask())

[<Obsolete "From version 0.4.0 onward, 'ValueTask.FromResult' is deprecated in favor of 'ValueTask.fromResult'. It will be removed in an upcoming release.">]
let inline FromResult (value: 'T) = ValueTask<'T> value

[<Obsolete "From version 0.4.0 onward, 'ValueTask.ofIValueTaskSource' is deprecated in favor of 'ValueTask.ofSource'. It will be removed in an upcoming release.">]
let inline ofIValueTaskSource taskSource version = ofSource taskSource version


module Task =
let inline fromResult (value: 'U) : Task<'U> = Task.FromResult value
let inline ofAsync (async: Async<'T>) = task { return! async }
Expand Down Expand Up @@ -72,14 +64,12 @@ module Async =
let inline ofTask (task: Task<'T>) = Async.AwaitTask task
let inline ofUnitTask (task: Task) = Async.AwaitTask task
let inline toTask (async: Async<'T>) = task { return! async }
let inline bind binder (task: Async<'T>) : Async<'U> = ExtraTopLevelOperators.async { return! binder task }

let inline ignore (async': Async<'T>) = async {
let! _ = async'
return ()
}
let inline ignore (async: Async<'T>) = Async.Ignore async

let inline map mapper (async: Async<'T>) : Async<'U> = ExtraTopLevelOperators.async {
let! result = async
return mapper result
}

let inline bind binder (async: Async<'T>) : Async<'U> = ExtraTopLevelOperators.async { return! binder async }
42 changes: 22 additions & 20 deletions src/FSharp.Control.TaskSeq/Utils.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ open System.Threading.Tasks.Sources

[<AutoOpen>]
module ValueTaskExtensions =
type System.Threading.Tasks.ValueTask with

/// (Extension member) Gets a task that has already completed successfully.
static member inline CompletedTask: System.Threading.Tasks.ValueTask
/// Shims back-filling .NET 5+ functionality for use on netstandard2.1
type ValueTask with

/// (Extension member) Gets a ValueTask that has already completed successfully.
static member inline CompletedTask: ValueTask

module ValueTask =

Expand All @@ -24,13 +26,13 @@ module ValueTask =

/// <summary>
/// The function <paramref name="FromResult" /> is deprecated since version 0.4.0,
/// please use <paramref name="fromSource" /> in its stead. See <see cref="T:FSharp.Control.ValueTask.fromResult" />.
/// please use <paramref name="fromResult" /> in its stead. See <see cref="T:FSharp.Control.ValueTask.fromResult" />.
/// </summary>
[<Obsolete "From version 0.4.0 onward, 'ValueTask.FromResult' is deprecated in favor of 'ValueTask.fromResult'. It will be removed in an upcoming release.">]
val inline FromResult: value: 'T -> ValueTask<'T>

/// <summary>
/// Initialized a new instance of <see cref="ValueTask" /> with an <see cref="IValueTaskSource" /> representing
/// Initializes a new instance of <see cref="ValueTask" /> with an <see cref="IValueTaskSource" />
/// representing its operation.
/// </summary>
val inline ofSource: taskSource: IValueTaskSource<bool> -> version: int16 -> ValueTask<bool>
Expand All @@ -42,21 +44,24 @@ module ValueTask =
[<Obsolete "From version 0.4.0 onward, 'ValueTask.ofIValueTaskSource' is deprecated in favor of 'ValueTask.ofSource'. It will be removed in an upcoming release.">]
val inline ofIValueTaskSource: taskSource: IValueTaskSource<bool> -> version: int16 -> ValueTask<bool>

/// Creates a ValueTask form a Task<'T>
/// Creates a ValueTask from a Task<'T>
val inline ofTask: task: Task<'T> -> ValueTask<'T>

/// Ignore a ValueTask<'T>, returns a non-generic ValueTask.
val inline ignore: vtask: ValueTask<'T> -> ValueTask
/// Convert a ValueTask<'T> into a non-generic ValueTask, ignoring the result
val inline ignore: valueTask: ValueTask<'T> -> ValueTask

module Task =

/// Convert an Async<'T> into a Task<'T>
/// Creates a Task<'U> that's completed successfully with the specified result.
val inline fromResult: value: 'U -> Task<'U>

/// Starts the `Async<'T>` computation, returning the associated `Task<'T>`
val inline ofAsync: async: Async<'T> -> Task<'T>

/// Convert a unit-task into a Task<unit>
/// Convert a non-generic Task into a Task<unit>
val inline ofTask: task': Task -> Task<unit>

/// Convert a non-task function into a task-returning function
/// Convert a plain function into a task-returning function
val inline apply: func: ('a -> 'b) -> ('a -> Task<'b>)

/// Convert a Task<'T> into an Async<'T>
Expand All @@ -66,8 +71,8 @@ module Task =
val inline toValueTask: task: Task<'T> -> ValueTask<'T>

/// <summary>
/// Convert a ValueTask&lt;'T> to a Task&lt;'T>. To use a non-generic ValueTask,
/// consider using: <paramref name="myValueTask |> Task.ofValueTask |> Task.ofTask" />.
/// Convert a ValueTask&lt;'T> to a Task&lt;'T>. For a non-generic ValueTask,
/// consider: <paramref name="myValueTask |> Task.ofValueTask |> Task.ofTask" />.
/// </summary>
val inline ofValueTask: valueTask: ValueTask<'T> -> Task<'T>

Expand All @@ -80,25 +85,22 @@ module Task =
/// Bind a Task<'T>
val inline bind: binder: ('T -> #Task<'U>) -> task: Task<'T> -> Task<'U>

/// Create a task from a value
val inline fromResult: value: 'U -> Task<'U>

module Async =

/// Convert an Task<'T> into an Async<'T>
val inline ofTask: task: Task<'T> -> Async<'T>

/// Convert a unit-task into an Async<unit>
/// Convert a non-generic Task into an Async<unit>
val inline ofUnitTask: task: Task -> Async<unit>

/// Convert a Task<'T> into an Async<'T>
/// Starts the `Async<'T>` computation, returning the associated `Task<'T>`
val inline toTask: async: Async<'T> -> Task<'T>

/// Convert an Async<'T> into an Async<unit>, ignoring the result
val inline ignore: async': Async<'T> -> Async<unit>
val inline ignore: async: Async<'T> -> Async<unit>

/// Map an Async<'T>
val inline map: mapper: ('T -> 'U) -> async: Async<'T> -> Async<'U>

/// Bind an Async<'T>
val inline bind: binder: (Async<'T> -> Async<'U>) -> task: Async<'T> -> Async<'U>
val inline bind: binder: (Async<'T> -> Async<'U>) -> async: Async<'T> -> Async<'U>

0 comments on commit f6ff7ab

Please sign in to comment.