diff --git a/README.md b/README.md index 8ef9bbd9..afa82085 100644 --- a/README.md +++ b/README.md @@ -13,37 +13,115 @@ documentation will be added soon(ish): ```f# module TaskSeq = - val toList: t: taskSeq<'T> -> 'T list - val toArray: taskSeq: taskSeq<'T> -> 'T[] - val empty<'T> : IAsyncEnumerable<'T> - val ofArray: array: 'T[] -> IAsyncEnumerable<'T> - val ofList: list: 'T list -> IAsyncEnumerable<'T> - val ofSeq: sequence: seq<'T> -> IAsyncEnumerable<'T> - val ofResizeArray: data: ResizeArray<'T> -> IAsyncEnumerable<'T> - val ofTaskSeq: sequence: seq<#Task<'T>> -> IAsyncEnumerable<'T> - val ofTaskList: list: #Task<'T> list -> IAsyncEnumerable<'T> - val ofTaskArray: array: #Task<'T> array -> IAsyncEnumerable<'T> - val ofAsyncSeq: sequence: seq> -> IAsyncEnumerable<'T> - val ofAsyncList: list: Async<'T> list -> IAsyncEnumerable<'T> - val ofAsyncArray: array: Async<'T> array -> IAsyncEnumerable<'T> - val toArrayAsync: taskSeq: taskSeq<'a> -> Task<'a[]> - val toListAsync: taskSeq: taskSeq<'a> -> Task<'a list> - val toResizeArrayAsync: taskSeq: taskSeq<'a> -> Task> - val toIListAsync: taskSeq: taskSeq<'a> -> Task> - val toSeqCachedAsync: taskSeq: taskSeq<'a> -> Task> - val iter: action: ('a -> unit) -> taskSeq: taskSeq<'a> -> Task - val iteri: action: (int -> 'a -> unit) -> taskSeq: taskSeq<'a> -> Task - val iterAsync: action: ('a -> #Task) -> taskSeq: taskSeq<'a> -> Task - val iteriAsync: action: (int -> 'a -> #Task) -> taskSeq: taskSeq<'a> -> Task - val map: mapper: ('T -> 'U) -> taskSeq: taskSeq<'T> -> IAsyncEnumerable<'U> - val mapi: mapper: (int -> 'T -> 'U) -> taskSeq: taskSeq<'T> -> IAsyncEnumerable<'U> - val mapAsync: mapper: ('a -> #Task<'c>) -> taskSeq: taskSeq<'a> -> IAsyncEnumerable<'c> - val mapiAsync: mapper: (int -> 'a -> #Task<'c>) -> taskSeq: taskSeq<'a> -> IAsyncEnumerable<'c> - val collect: binder: ('T -> #IAsyncEnumerable<'U>) -> taskSeq: taskSeq<'T> -> IAsyncEnumerable<'U> - val collectSeq: binder: ('T -> #seq<'U>) -> taskSeq: taskSeq<'T> -> IAsyncEnumerable<'U> - val collectAsync: binder: ('T -> #Task<'b>) -> taskSeq: taskSeq<'T> -> taskSeq<'U> when 'b :> IAsyncEnumerable<'U> - val collectSeqAsync: binder: ('T -> #Task<'b>) -> taskSeq: taskSeq<'T> -> taskSeq<'U> when 'b :> seq<'U> - val zip: taskSeq1: taskSeq<'a> -> taskSeq2: taskSeq<'b> -> IAsyncEnumerable<'a * 'b> - val fold: folder: ('State -> 'T -> 'State) -> state: 'State -> taskSeq: IAsyncEnumerable<'T> -> Task<'State> - val foldAsync: folder: ('State -> 'T -> #Task<'State>) -> state: 'State -> taskSeq: IAsyncEnumerable<'T> -> Task<'State> + open System.Collections.Generic + open System.Threading.Tasks + open FSharpy.TaskSeqBuilders + + /// Initialize an empty taskSeq. + val empty<'T> : taskSeq<'T> + + /// Returns taskSeq as an array. This function is blocking until the sequence is exhausted and will properly dispose of the resources. + val toList: t: taskSeq<'T> -> 'T list + + /// Returns taskSeq as an array. This function is blocking until the sequence is exhausted and will properly dispose of the resources. + val toArray: taskSeq: taskSeq<'T> -> 'T[] + + /// Returns taskSeq as a seq, similar to Seq.cached. This function is blocking until the sequence is exhausted and will properly dispose of the resources. + val toSeqCached: taskSeq: taskSeq<'T> -> seq<'T> + + /// Unwraps the taskSeq as a Task>. This function is non-blocking. + val toArrayAsync: taskSeq: taskSeq<'T> -> Task<'T[]> + + /// Unwraps the taskSeq as a Task>. This function is non-blocking. + val toListAsync: taskSeq: taskSeq<'T> -> Task<'T list> + + /// Unwraps the taskSeq as a Task>. This function is non-blocking. + val toResizeArrayAsync: taskSeq: taskSeq<'T> -> Task> + + /// Unwraps the taskSeq as a Task>. This function is non-blocking. + val toIListAsync: taskSeq: taskSeq<'T> -> Task> + + /// Unwraps the taskSeq as a Task>. This function is non-blocking, + /// exhausts the sequence and caches the results of the tasks in the sequence. + val toSeqCachedAsync: taskSeq: taskSeq<'T> -> Task> + + /// Create a taskSeq of an array. + val ofArray: array: 'T[] -> taskSeq<'T> + + /// Create a taskSeq of a list. + val ofList: list: 'T list -> taskSeq<'T> + + /// Create a taskSeq of a seq. + val ofSeq: sequence: seq<'T> -> taskSeq<'T> + + /// Create a taskSeq of a ResizeArray, aka List. + val ofResizeArray: data: ResizeArray<'T> -> taskSeq<'T> + + /// Create a taskSeq of a sequence of tasks, that may already have hot-started. + val ofTaskSeq: sequence: seq<#Task<'T>> -> taskSeq<'T> + + /// Create a taskSeq of a list of tasks, that may already have hot-started. + val ofTaskList: list: #Task<'T> list -> taskSeq<'T> + + /// Create a taskSeq of an array of tasks, that may already have hot-started. + val ofTaskArray: array: #Task<'T> array -> taskSeq<'T> + + /// Create a taskSeq of a seq of async. + val ofAsyncSeq: sequence: seq> -> taskSeq<'T> + + /// Create a taskSeq of a list of async. + val ofAsyncList: list: Async<'T> list -> taskSeq<'T> + + /// Create a taskSeq of an array of async. + val ofAsyncArray: array: Async<'T> array -> taskSeq<'T> + + /// Iterates over the taskSeq applying the action function to each item. This function is non-blocking + /// exhausts the sequence as soon as the task is evaluated. + val iter: action: ('T -> unit) -> taskSeq: taskSeq<'T> -> Task + + /// Iterates over the taskSeq applying the action function to each item. This function is non-blocking, + /// exhausts the sequence as soon as the task is evaluated. + val iteri: action: (int -> 'T -> unit) -> taskSeq: taskSeq<'T> -> Task + + /// Iterates over the taskSeq applying the async action to each item. This function is non-blocking + /// exhausts the sequence as soon as the task is evaluated. + val iterAsync: action: ('T -> #Task) -> taskSeq: taskSeq<'T> -> Task + + /// Iterates over the taskSeq, applying the async action to each item. This function is non-blocking, + /// exhausts the sequence as soon as the task is evaluated. + val iteriAsync: action: (int -> 'T -> #Task) -> taskSeq: taskSeq<'T> -> Task + + /// Maps over the taskSeq, applying the mapper function to each item. This function is non-blocking. + val map: mapper: ('T -> 'U) -> taskSeq: taskSeq<'T> -> taskSeq<'U> + + /// Maps over the taskSeq with an index, applying the mapper function to each item. This function is non-blocking. + val mapi: mapper: (int -> 'T -> 'U) -> taskSeq: taskSeq<'T> -> taskSeq<'U> + + /// Maps over the taskSeq, applying the async mapper function to each item. This function is non-blocking. + val mapAsync: mapper: ('T -> #Task<'U>) -> taskSeq: taskSeq<'T> -> taskSeq<'U> + + /// Maps over the taskSeq with an index, applying the async mapper function to each item. This function is non-blocking. + val mapiAsync: mapper: (int -> 'T -> #Task<'U>) -> taskSeq: taskSeq<'T> -> taskSeq<'U> + + /// Applies the given function to the items in the taskSeq and concatenates all the results in order. + val collect: binder: ('T -> #taskSeq<'U>) -> taskSeq: taskSeq<'T> -> taskSeq<'U> + + /// Applies the given function to the items in the taskSeq and concatenates all the results in order. + val collectSeq: binder: ('T -> #seq<'U>) -> taskSeq: taskSeq<'T> -> taskSeq<'U> + + /// Applies the given async function to the items in the taskSeq and concatenates all the results in order. + val collectAsync: binder: ('T -> #Task<'TSeqU>) -> taskSeq: taskSeq<'T> -> taskSeq<'U> when 'TSeqU :> taskSeq<'U> + + /// Applies the given async function to the items in the taskSeq and concatenates all the results in order. + val collectSeqAsync: binder: ('T -> #Task<'SeqU>) -> taskSeq: taskSeq<'T> -> taskSeq<'U> when 'SeqU :> seq<'U> + + /// Zips two task sequences, returning a taskSeq of the tuples of each sequence, in order. May raise ArgumentException + /// if the sequences are or unequal length. + val zip: taskSeq1: taskSeq<'T> -> taskSeq2: taskSeq<'U> -> taskSeq<'T * 'U> + + /// Applies a function to each element of the task sequence, threading an accumulator argument through the computation. + val fold: folder: ('State -> 'T -> 'State) -> state: 'State -> taskSeq: taskSeq<'T> -> Task<'State> + + /// Applies an async function to each element of the task sequence, threading an accumulator argument through the computation. + val foldAsync: folder: ('State -> 'T -> #Task<'State>) -> state: 'State -> taskSeq: taskSeq<'T> -> Task<'State> ``` diff --git a/src/FSharpy.TaskSeq.Test/TaskSeq.Collect.Tests.fs b/src/FSharpy.TaskSeq.Test/TaskSeq.Collect.Tests.fs index 4a437ade..3d405e2d 100644 --- a/src/FSharpy.TaskSeq.Test/TaskSeq.Collect.Tests.fs +++ b/src/FSharpy.TaskSeq.Test/TaskSeq.Collect.Tests.fs @@ -1,4 +1,4 @@ -module FSharpy.TaskSeq.Tests.Collect +module FSharpy.Tests.Collect open Xunit open FsUnit.Xunit diff --git a/src/FSharpy.TaskSeq.Test/TaskSeq.Fold.Tests.fs b/src/FSharpy.TaskSeq.Test/TaskSeq.Fold.Tests.fs index b21a8075..fa6e310b 100644 --- a/src/FSharpy.TaskSeq.Test/TaskSeq.Fold.Tests.fs +++ b/src/FSharpy.TaskSeq.Test/TaskSeq.Fold.Tests.fs @@ -1,4 +1,4 @@ -module FSharpy.TaskSeq.Tests.Fold +module FSharpy.Tests.Fold open System.Text open Xunit diff --git a/src/FSharpy.TaskSeq.Test/TaskSeq.Iter.Tests.fs b/src/FSharpy.TaskSeq.Test/TaskSeq.Iter.Tests.fs index 7825b64c..f8418b21 100644 --- a/src/FSharpy.TaskSeq.Test/TaskSeq.Iter.Tests.fs +++ b/src/FSharpy.TaskSeq.Test/TaskSeq.Iter.Tests.fs @@ -1,4 +1,4 @@ -module FSharpy.TaskSeq.Tests.Iter +module FSharpy.Tests.Iter open Xunit open FsUnit.Xunit diff --git a/src/FSharpy.TaskSeq.Test/TaskSeq.Map.Tests.fs b/src/FSharpy.TaskSeq.Test/TaskSeq.Map.Tests.fs index 0392a28e..46dc1154 100644 --- a/src/FSharpy.TaskSeq.Test/TaskSeq.Map.Tests.fs +++ b/src/FSharpy.TaskSeq.Test/TaskSeq.Map.Tests.fs @@ -1,4 +1,4 @@ -module FSharpy.TaskSeq.Tests.Map +module FSharpy.Tests.Map open Xunit open FsUnit.Xunit diff --git a/src/FSharpy.TaskSeq.Test/TaskSeq.OfXXX.Tests.fs b/src/FSharpy.TaskSeq.Test/TaskSeq.OfXXX.Tests.fs index 5a15377b..0cb51387 100644 --- a/src/FSharpy.TaskSeq.Test/TaskSeq.OfXXX.Tests.fs +++ b/src/FSharpy.TaskSeq.Test/TaskSeq.OfXXX.Tests.fs @@ -1,4 +1,4 @@ -module FSharpy.TaskSeq.Tests.``Conversion-From`` +module FSharpy.Tests.``Conversion-From`` open Xunit open FsUnit.Xunit diff --git a/src/FSharpy.TaskSeq.Test/TaskSeq.PocTests.fs b/src/FSharpy.TaskSeq.Test/TaskSeq.PocTests.fs index 5b00da6e..23d4c003 100644 --- a/src/FSharpy.TaskSeq.Test/TaskSeq.PocTests.fs +++ b/src/FSharpy.TaskSeq.Test/TaskSeq.PocTests.fs @@ -1,4 +1,4 @@ -namespace FSharpy.TaskSeq.Tests +namespace FSharpy.Tests open Xunit open FsUnit.Xunit diff --git a/src/FSharpy.TaskSeq.Test/TaskSeq.Tests.Utility.fs b/src/FSharpy.TaskSeq.Test/TaskSeq.Tests.Utility.fs index 83cab90b..acec581e 100644 --- a/src/FSharpy.TaskSeq.Test/TaskSeq.Tests.Utility.fs +++ b/src/FSharpy.TaskSeq.Test/TaskSeq.Tests.Utility.fs @@ -1,4 +1,4 @@ -module FSharpy.TaskSeq.Tests.``Utility functions`` +module FSharpy.Tests.``Utility functions`` open Xunit open FsUnit.Xunit diff --git a/src/FSharpy.TaskSeq.Test/TaskSeq.Tests.fs b/src/FSharpy.TaskSeq.Test/TaskSeq.Tests.fs index a8978500..a8d4a0dc 100644 --- a/src/FSharpy.TaskSeq.Test/TaskSeq.Tests.fs +++ b/src/FSharpy.TaskSeq.Test/TaskSeq.Tests.fs @@ -1,4 +1,4 @@ -module FSharpy.TaskSeq.Tests.``taskSeq Computation Expression`` +module FSharpy.Tests.``taskSeq Computation Expression`` open Xunit open FsUnit.Xunit diff --git a/src/FSharpy.TaskSeq.Test/TaskSeq.ToXXX.Tests.fs b/src/FSharpy.TaskSeq.Test/TaskSeq.ToXXX.Tests.fs index 27ac1230..5d57feca 100644 --- a/src/FSharpy.TaskSeq.Test/TaskSeq.ToXXX.Tests.fs +++ b/src/FSharpy.TaskSeq.Test/TaskSeq.ToXXX.Tests.fs @@ -1,4 +1,4 @@ -module FSharpy.TaskSeq.Tests.``Conversion-To`` +module FSharpy.Tests.``Conversion-To`` open Xunit open FsUnit.Xunit diff --git a/src/FSharpy.TaskSeq.Test/TestUtils.fs b/src/FSharpy.TaskSeq.Test/TestUtils.fs index 4eef93d7..0f16920d 100644 --- a/src/FSharpy.TaskSeq.Test/TestUtils.fs +++ b/src/FSharpy.TaskSeq.Test/TestUtils.fs @@ -1,4 +1,4 @@ -namespace FSharpy.TaskSeq.Tests +namespace FSharpy.Tests open System open System.Threading diff --git a/src/FSharpy.TaskSeq/FSharpy.TaskSeq.fsproj b/src/FSharpy.TaskSeq/FSharpy.TaskSeq.fsproj index 5e2eadd7..cbb2cfa5 100644 --- a/src/FSharpy.TaskSeq/FSharpy.TaskSeq.fsproj +++ b/src/FSharpy.TaskSeq/FSharpy.TaskSeq.fsproj @@ -5,10 +5,19 @@ true + + + + + + + + + diff --git a/src/FSharpy.TaskSeq/TaskSeq.fsi b/src/FSharpy.TaskSeq/TaskSeq.fsi new file mode 100644 index 00000000..548877a0 --- /dev/null +++ b/src/FSharpy.TaskSeq/TaskSeq.fsi @@ -0,0 +1,114 @@ +namespace FSharpy + +module TaskSeq = + open System.Collections.Generic + open System.Threading.Tasks + open FSharpy.TaskSeqBuilders + + /// Initialize an empty taskSeq. + val empty<'T> : taskSeq<'T> + + /// Returns taskSeq as an array. This function is blocking until the sequence is exhausted and will properly dispose of the resources. + val toList: t: taskSeq<'T> -> 'T list + + /// Returns taskSeq as an array. This function is blocking until the sequence is exhausted and will properly dispose of the resources. + val toArray: taskSeq: taskSeq<'T> -> 'T[] + + /// Returns taskSeq as a seq, similar to Seq.cached. This function is blocking until the sequence is exhausted and will properly dispose of the resources. + val toSeqCached: taskSeq: taskSeq<'T> -> seq<'T> + + /// Unwraps the taskSeq as a Task>. This function is non-blocking. + val toArrayAsync: taskSeq: taskSeq<'T> -> Task<'T[]> + + /// Unwraps the taskSeq as a Task>. This function is non-blocking. + val toListAsync: taskSeq: taskSeq<'T> -> Task<'T list> + + /// Unwraps the taskSeq as a Task>. This function is non-blocking. + val toResizeArrayAsync: taskSeq: taskSeq<'T> -> Task> + + /// Unwraps the taskSeq as a Task>. This function is non-blocking. + val toIListAsync: taskSeq: taskSeq<'T> -> Task> + + /// Unwraps the taskSeq as a Task>. This function is non-blocking, + /// exhausts the sequence and caches the results of the tasks in the sequence. + val toSeqCachedAsync: taskSeq: taskSeq<'T> -> Task> + + /// Create a taskSeq of an array. + val ofArray: array: 'T[] -> taskSeq<'T> + + /// Create a taskSeq of a list. + val ofList: list: 'T list -> taskSeq<'T> + + /// Create a taskSeq of a seq. + val ofSeq: sequence: seq<'T> -> taskSeq<'T> + + /// Create a taskSeq of a ResizeArray, aka List. + val ofResizeArray: data: ResizeArray<'T> -> taskSeq<'T> + + /// Create a taskSeq of a sequence of tasks, that may already have hot-started. + val ofTaskSeq: sequence: seq<#Task<'T>> -> taskSeq<'T> + + /// Create a taskSeq of a list of tasks, that may already have hot-started. + val ofTaskList: list: #Task<'T> list -> taskSeq<'T> + + /// Create a taskSeq of an array of tasks, that may already have hot-started. + val ofTaskArray: array: #Task<'T> array -> taskSeq<'T> + + /// Create a taskSeq of a seq of async. + val ofAsyncSeq: sequence: seq> -> taskSeq<'T> + + /// Create a taskSeq of a list of async. + val ofAsyncList: list: Async<'T> list -> taskSeq<'T> + + /// Create a taskSeq of an array of async. + val ofAsyncArray: array: Async<'T> array -> taskSeq<'T> + + /// Iterates over the taskSeq applying the action function to each item. This function is non-blocking + /// exhausts the sequence as soon as the task is evaluated. + val iter: action: ('T -> unit) -> taskSeq: taskSeq<'T> -> Task + + /// Iterates over the taskSeq applying the action function to each item. This function is non-blocking, + /// exhausts the sequence as soon as the task is evaluated. + val iteri: action: (int -> 'T -> unit) -> taskSeq: taskSeq<'T> -> Task + + /// Iterates over the taskSeq applying the async action to each item. This function is non-blocking + /// exhausts the sequence as soon as the task is evaluated. + val iterAsync: action: ('T -> #Task) -> taskSeq: taskSeq<'T> -> Task + + /// Iterates over the taskSeq, applying the async action to each item. This function is non-blocking, + /// exhausts the sequence as soon as the task is evaluated. + val iteriAsync: action: (int -> 'T -> #Task) -> taskSeq: taskSeq<'T> -> Task + + /// Maps over the taskSeq, applying the mapper function to each item. This function is non-blocking. + val map: mapper: ('T -> 'U) -> taskSeq: taskSeq<'T> -> taskSeq<'U> + + /// Maps over the taskSeq with an index, applying the mapper function to each item. This function is non-blocking. + val mapi: mapper: (int -> 'T -> 'U) -> taskSeq: taskSeq<'T> -> taskSeq<'U> + + /// Maps over the taskSeq, applying the async mapper function to each item. This function is non-blocking. + val mapAsync: mapper: ('T -> #Task<'U>) -> taskSeq: taskSeq<'T> -> taskSeq<'U> + + /// Maps over the taskSeq with an index, applying the async mapper function to each item. This function is non-blocking. + val mapiAsync: mapper: (int -> 'T -> #Task<'U>) -> taskSeq: taskSeq<'T> -> taskSeq<'U> + + /// Applies the given function to the items in the taskSeq and concatenates all the results in order. + val collect: binder: ('T -> #taskSeq<'U>) -> taskSeq: taskSeq<'T> -> taskSeq<'U> + + /// Applies the given function to the items in the taskSeq and concatenates all the results in order. + val collectSeq: binder: ('T -> #seq<'U>) -> taskSeq: taskSeq<'T> -> taskSeq<'U> + + /// Applies the given async function to the items in the taskSeq and concatenates all the results in order. + val collectAsync: binder: ('T -> #Task<'TSeqU>) -> taskSeq: taskSeq<'T> -> taskSeq<'U> when 'TSeqU :> taskSeq<'U> + + /// Applies the given async function to the items in the taskSeq and concatenates all the results in order. + val collectSeqAsync: binder: ('T -> #Task<'SeqU>) -> taskSeq: taskSeq<'T> -> taskSeq<'U> when 'SeqU :> seq<'U> + + /// Zips two task sequences, returning a taskSeq of the tuples of each sequence, in order. May raise ArgumentException + /// if the sequences are or unequal length. + val zip: taskSeq1: taskSeq<'T> -> taskSeq2: taskSeq<'U> -> taskSeq<'T * 'U> + + /// Applies a function to each element of the task sequence, threading an accumulator argument through the computation. + val fold: folder: ('State -> 'T -> 'State) -> state: 'State -> taskSeq: taskSeq<'T> -> Task<'State> + + /// Applies an async function to each element of the task sequence, threading an accumulator argument through the computation. + val foldAsync: folder: ('State -> 'T -> #Task<'State>) -> state: 'State -> taskSeq: taskSeq<'T> -> Task<'State>