diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.coreclr.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.coreclr.fs index 10c4389cb95..932a849aa54 100644 --- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.coreclr.fs +++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.coreclr.fs @@ -181,6 +181,63 @@ Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.ICom Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] Structural[T]() Microsoft.FSharp.Collections.ComparisonIdentity: System.String ToString() Microsoft.FSharp.Collections.ComparisonIdentity: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void .ctor() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: TResult Value +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void .ctor(TResult) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+IOutOfBand: Void StopFurtherProcessing(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Consumer`2 Create[V](IOutOfBand, System.Nullable`1[System.Int32], Consumer`2) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Int32 PipeIdx +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Int32 get_PipeIdx() +Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T]: ISeq`1 Compose[TResult](ISeqFactory`2) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T]: a ForEach[a](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit],a]) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Void .ctor(a, b) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: a _1 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: b _2 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Void .ctor(a, b, c) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: a _1 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: b _2 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: c _3 +Microsoft.FSharp.Collections.ComposerModule+Core: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+IOutOfBand +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c] +Microsoft.FSharp.Collections.ComposerModule+Core: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule: Microsoft.FSharp.Collections.ComposerModule+Core +Microsoft.FSharp.Collections.ComposerModule: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule: System.Type GetType() Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Boolean Equals(System.Object) Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Cons Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Empty @@ -404,6 +461,7 @@ Microsoft.FSharp.Collections.SeqModule: Boolean Exists[T](Microsoft.FSharp.Core. Microsoft.FSharp.Collections.SeqModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) Microsoft.FSharp.Collections.SeqModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Boolean IsEmpty[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: ISeq`1 ToComposer[T](System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs index c452c3f31c4..46020db9e40 100644 --- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs +++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs @@ -194,6 +194,63 @@ Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.ICom Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] Structural[T]() Microsoft.FSharp.Collections.ComparisonIdentity: System.String ToString() Microsoft.FSharp.Collections.ComparisonIdentity: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void .ctor() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: TResult Value +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void .ctor(TResult) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+IOutOfBand: Void StopFurtherProcessing(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Consumer`2 Create[V](IOutOfBand, System.Nullable`1[System.Int32], Consumer`2) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Int32 PipeIdx +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Int32 get_PipeIdx() +Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T]: ISeq`1 Compose[TResult](ISeqFactory`2) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T]: a ForEach[a](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit],a]) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Void .ctor(a, b) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: a _1 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: b _2 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Void .ctor(a, b, c) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: a _1 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: b _2 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: c _3 +Microsoft.FSharp.Collections.ComposerModule+Core: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+IOutOfBand +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c] +Microsoft.FSharp.Collections.ComposerModule+Core: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule: Microsoft.FSharp.Collections.ComposerModule+Core +Microsoft.FSharp.Collections.ComposerModule: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule: System.Type GetType() Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Boolean Equals(System.Object) Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Cons Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Empty @@ -419,6 +476,7 @@ Microsoft.FSharp.Collections.SeqModule: Boolean Exists[T](Microsoft.FSharp.Core. Microsoft.FSharp.Collections.SeqModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) Microsoft.FSharp.Collections.SeqModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Boolean IsEmpty[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: ISeq`1 ToComposer[T](System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable259.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable259.fs index 8e5337ef4a8..0464eb1580f 100644 --- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable259.fs +++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable259.fs @@ -181,6 +181,63 @@ Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.ICom Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] Structural[T]() Microsoft.FSharp.Collections.ComparisonIdentity: System.String ToString() Microsoft.FSharp.Collections.ComparisonIdentity: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void .ctor() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: TResult Value +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void .ctor(TResult) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+IOutOfBand: Void StopFurtherProcessing(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Consumer`2 Create[V](IOutOfBand, System.Nullable`1[System.Int32], Consumer`2) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Int32 PipeIdx +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Int32 get_PipeIdx() +Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T]: ISeq`1 Compose[TResult](ISeqFactory`2) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T]: a ForEach[a](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit],a]) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Void .ctor(a, b) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: a _1 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: b _2 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Void .ctor(a, b, c) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: a _1 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: b _2 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: c _3 +Microsoft.FSharp.Collections.ComposerModule+Core: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+IOutOfBand +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c] +Microsoft.FSharp.Collections.ComposerModule+Core: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule: Microsoft.FSharp.Collections.ComposerModule+Core +Microsoft.FSharp.Collections.ComposerModule: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule: System.Type GetType() Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Boolean Equals(System.Object) Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Cons Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Empty @@ -406,6 +463,7 @@ Microsoft.FSharp.Collections.SeqModule: Boolean Exists[T](Microsoft.FSharp.Core. Microsoft.FSharp.Collections.SeqModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) Microsoft.FSharp.Collections.SeqModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Boolean IsEmpty[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: ISeq`1 ToComposer[T](System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable47.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable47.fs index 531eebf0e8f..15ceb66e7d8 100644 --- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable47.fs +++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable47.fs @@ -178,6 +178,63 @@ Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.ICom Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] Structural[T]() Microsoft.FSharp.Collections.ComparisonIdentity: System.String ToString() Microsoft.FSharp.Collections.ComparisonIdentity: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void .ctor() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: TResult Value +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void .ctor(TResult) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+IOutOfBand: Void StopFurtherProcessing(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Consumer`2 Create[V](IOutOfBand, System.Nullable`1[System.Int32], Consumer`2) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Int32 PipeIdx +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Int32 get_PipeIdx() +Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T]: ISeq`1 Compose[TResult](ISeqFactory`2) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T]: a ForEach[a](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit],a]) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Void .ctor(a, b) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: a _1 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: b _2 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Void .ctor(a, b, c) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: a _1 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: b _2 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: c _3 +Microsoft.FSharp.Collections.ComposerModule+Core: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+IOutOfBand +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c] +Microsoft.FSharp.Collections.ComposerModule+Core: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule: Microsoft.FSharp.Collections.ComposerModule+Core +Microsoft.FSharp.Collections.ComposerModule: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule: System.Type GetType() Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Boolean Equals(System.Object) Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Cons Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Empty @@ -403,6 +460,7 @@ Microsoft.FSharp.Collections.SeqModule: Boolean Exists[T](Microsoft.FSharp.Core. Microsoft.FSharp.Collections.SeqModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) Microsoft.FSharp.Collections.SeqModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Boolean IsEmpty[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: ISeq`1 ToComposer[T](System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable7.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable7.fs index 7d320ad8483..8e71c1daaee 100644 --- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable7.fs +++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable7.fs @@ -194,6 +194,63 @@ Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.ICom Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] Structural[T]() Microsoft.FSharp.Collections.ComparisonIdentity: System.String ToString() Microsoft.FSharp.Collections.ComparisonIdentity: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void .ctor() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: TResult Value +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void .ctor(TResult) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+IOutOfBand: Void StopFurtherProcessing(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Consumer`2 Create[V](IOutOfBand, System.Nullable`1[System.Int32], Consumer`2) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Int32 PipeIdx +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Int32 get_PipeIdx() +Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T]: ISeq`1 Compose[TResult](ISeqFactory`2) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T]: a ForEach[a](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit],a]) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Void .ctor(a, b) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: a _1 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: b _2 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Void .ctor(a, b, c) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: a _1 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: b _2 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: c _3 +Microsoft.FSharp.Collections.ComposerModule+Core: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+IOutOfBand +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c] +Microsoft.FSharp.Collections.ComposerModule+Core: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule: Microsoft.FSharp.Collections.ComposerModule+Core +Microsoft.FSharp.Collections.ComposerModule: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule: System.Type GetType() Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Boolean Equals(System.Object) Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Cons Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Empty @@ -419,6 +476,7 @@ Microsoft.FSharp.Collections.SeqModule: Boolean Exists[T](Microsoft.FSharp.Core. Microsoft.FSharp.Collections.SeqModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) Microsoft.FSharp.Collections.SeqModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Boolean IsEmpty[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: ISeq`1 ToComposer[T](System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable78.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable78.fs index f731fcdbcc0..c5601ff12ef 100644 --- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable78.fs +++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable78.fs @@ -181,6 +181,63 @@ Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.ICom Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] Structural[T]() Microsoft.FSharp.Collections.ComparisonIdentity: System.String ToString() Microsoft.FSharp.Collections.ComparisonIdentity: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void .ctor() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: TResult Value +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void .ctor(TResult) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+IOutOfBand: Void StopFurtherProcessing(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Consumer`2 Create[V](IOutOfBand, System.Nullable`1[System.Int32], Consumer`2) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Int32 PipeIdx +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Int32 get_PipeIdx() +Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T]: ISeq`1 Compose[TResult](ISeqFactory`2) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T]: a ForEach[a](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit],a]) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Void .ctor(a, b) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: a _1 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: b _2 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Void .ctor(a, b, c) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: a _1 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: b _2 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: c _3 +Microsoft.FSharp.Collections.ComposerModule+Core: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+IOutOfBand +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c] +Microsoft.FSharp.Collections.ComposerModule+Core: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule: Microsoft.FSharp.Collections.ComposerModule+Core +Microsoft.FSharp.Collections.ComposerModule: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule: System.Type GetType() Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Boolean Equals(System.Object) Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Cons Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Empty @@ -406,6 +463,7 @@ Microsoft.FSharp.Collections.SeqModule: Boolean Exists[T](Microsoft.FSharp.Core. Microsoft.FSharp.Collections.SeqModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) Microsoft.FSharp.Collections.SeqModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Boolean IsEmpty[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: ISeq`1 ToComposer[T](System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) diff --git a/src/fsharp/FSharp.Core/FSharp.Core.fsproj b/src/fsharp/FSharp.Core/FSharp.Core.fsproj index 1909f2ddfb6..861202ebf44 100644 --- a/src/fsharp/FSharp.Core/FSharp.Core.fsproj +++ b/src/fsharp/FSharp.Core/FSharp.Core.fsproj @@ -86,6 +86,18 @@ Collections/collections.fs + + + Collections/seqcore.fsi + + + Collections/seqcore.fs + + + Collections/seqcomposer.fsi + + + Collections/seqcomposer.fs Collections/seq.fsi diff --git a/src/fsharp/FSharp.Core/seq.fs b/src/fsharp/FSharp.Core/seq.fs index d2cfe54622e..8aba11bd9ac 100644 --- a/src/fsharp/FSharp.Core/seq.fs +++ b/src/fsharp/FSharp.Core/seq.fs @@ -1,819 +1,5 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.FSharp.Collections - #nowarn "52" // The value has been copied to ensure the original is not mutated by this operation - - open System - open System.Diagnostics - open System.Collections - open System.Collections.Generic - open Microsoft.FSharp.Core - open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators - open Microsoft.FSharp.Core.Operators - open Microsoft.FSharp.Control - open Microsoft.FSharp.Collections - - module IEnumerator = - - - let noReset() = raise (new System.NotSupportedException(SR.GetString(SR.resetNotSupported))) - let notStarted() = raise (new System.InvalidOperationException(SR.GetString(SR.enumerationNotStarted))) - let alreadyFinished() = raise (new System.InvalidOperationException(SR.GetString(SR.enumerationAlreadyFinished))) - let check started = if not started then notStarted() - let dispose (r : System.IDisposable) = r.Dispose() - - let cast (e : IEnumerator) : IEnumerator<'T> = - { new IEnumerator<'T> with - member x.Current = unbox<'T> e.Current - interface IEnumerator with - member x.Current = unbox<'T> e.Current :> obj - member x.MoveNext() = e.MoveNext() - member x.Reset() = noReset() - interface System.IDisposable with - member x.Dispose() = - match e with - | :? System.IDisposable as e -> e.Dispose() - | _ -> () } - - /// A concrete implementation of an enumerator that returns no values - [] - type EmptyEnumerator<'T>() = - let mutable started = false - interface IEnumerator<'T> with - member x.Current = - check started - (alreadyFinished() : 'T) - - interface System.Collections.IEnumerator with - member x.Current = - check started - (alreadyFinished() : obj) - member x.MoveNext() = - if not started then started <- true - false - member x.Reset() = noReset() - interface System.IDisposable with - member x.Dispose() = () - - let Empty<'T> () = (new EmptyEnumerator<'T>() :> IEnumerator<'T>) - - let rec tryItem index (e : IEnumerator<'T>) = - if not (e.MoveNext()) then None - elif index = 0 then Some(e.Current) - else tryItem (index-1) e - - let rec nth index (e : IEnumerator<'T>) = - if not (e.MoveNext()) then - let shortBy = index + 1 - invalidArgFmt "index" - "{0}\nseq was short by {1} {2}" - [|SR.GetString SR.notEnoughElements; shortBy; (if shortBy = 1 then "element" else "elements")|] - if index = 0 then e.Current - else nth (index-1) e - - [] - type MapEnumeratorState = - | NotStarted - | InProcess - | Finished - - [] - type MapEnumerator<'T> () = - let mutable state = NotStarted - [] - val mutable private curr : 'T - - member this.GetCurrent () = - match state with - | NotStarted -> notStarted() - | Finished -> alreadyFinished() - | InProcess -> () - this.curr - - abstract DoMoveNext : byref<'T> -> bool - abstract Dispose : unit -> unit - - interface IEnumerator<'T> with - member this.Current = this.GetCurrent() - - interface IEnumerator with - member this.Current = box(this.GetCurrent()) - member this.MoveNext () = - state <- InProcess - if this.DoMoveNext(&this.curr) then - true - else - state <- Finished - false - member this.Reset() = noReset() - interface System.IDisposable with - member this.Dispose() = this.Dispose() - - let map f (e : IEnumerator<_>) : IEnumerator<_>= - upcast - { new MapEnumerator<_>() with - member this.DoMoveNext (curr : byref<_>) = - if e.MoveNext() then - curr <- (f e.Current) - true - else - false - member this.Dispose() = e.Dispose() - } - - let mapi f (e : IEnumerator<_>) : IEnumerator<_> = - let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let i = ref (-1) - upcast - { new MapEnumerator<_>() with - member this.DoMoveNext curr = - i := !i + 1 - if e.MoveNext() then - curr <- f.Invoke(!i, e.Current) - true - else - false - member this.Dispose() = e.Dispose() - } - - let map2 f (e1 : IEnumerator<_>) (e2 : IEnumerator<_>) : IEnumerator<_>= - let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - upcast - { new MapEnumerator<_>() with - member this.DoMoveNext curr = - let n1 = e1.MoveNext() - let n2 = e2.MoveNext() - if n1 && n2 then - curr <- f.Invoke(e1.Current, e2.Current) - true - else - false - member this.Dispose() = - try - e1.Dispose() - finally - e2.Dispose() - } - - let mapi2 f (e1 : IEnumerator<_>) (e2 : IEnumerator<_>) : IEnumerator<_> = - let f = OptimizedClosures.FSharpFunc<_,_,_,_>.Adapt(f) - let i = ref (-1) - upcast - { new MapEnumerator<_>() with - member this.DoMoveNext curr = - i := !i + 1 - if (e1.MoveNext() && e2.MoveNext()) then - curr <- f.Invoke(!i, e1.Current, e2.Current) - true - else - false - member this.Dispose() = - try - e1.Dispose() - finally - e2.Dispose() - } - - let map3 f (e1 : IEnumerator<_>) (e2 : IEnumerator<_>) (e3 : IEnumerator<_>) : IEnumerator<_> = - let f = OptimizedClosures.FSharpFunc<_,_,_,_>.Adapt(f) - upcast - { new MapEnumerator<_>() with - member this.DoMoveNext curr = - let n1 = e1.MoveNext() - let n2 = e2.MoveNext() - let n3 = e3.MoveNext() - - if n1 && n2 && n3 then - curr <- f.Invoke(e1.Current, e2.Current, e3.Current) - true - else - false - member this.Dispose() = - try - e1.Dispose() - finally - try - e2.Dispose() - finally - e3.Dispose() - } - - let choose f (e : IEnumerator<'T>) = - let started = ref false - let curr = ref None - let get() = check !started; (match !curr with None -> alreadyFinished() | Some x -> x) - { new IEnumerator<'U> with - member x.Current = get() - interface IEnumerator with - member x.Current = box (get()) - member x.MoveNext() = - if not !started then started := true - curr := None - while ((!curr).IsNone && e.MoveNext()) do - curr := f e.Current - Option.isSome !curr - member x.Reset() = noReset() - interface System.IDisposable with - member x.Dispose() = e.Dispose() } - - let filter f (e : IEnumerator<'T>) = - let started = ref false - let this = - { new IEnumerator<'T> with - member x.Current = check !started; e.Current - interface IEnumerator with - member x.Current = check !started; box e.Current - member x.MoveNext() = - let rec next() = - if not !started then started := true - e.MoveNext() && (f e.Current || next()) - next() - member x.Reset() = noReset() - interface System.IDisposable with - member x.Dispose() = e.Dispose() } - this - - let unfold f x : IEnumerator<_> = - let state = ref x - upcast - { new MapEnumerator<_>() with - member this.DoMoveNext curr = - match f !state with - | None -> false - | Some(r,s) -> - curr <- r - state := s - true - member this.Dispose() = () - } - - let upto lastOption f = - match lastOption with - | Some b when b<0 -> Empty() // a request for -ve length returns empty sequence - | _ -> - let unstarted = -1 // index value means unstarted (and no valid index) - let completed = -2 // index value means completed (and no valid index) - let unreachable = -3 // index is unreachable from 0,1,2,3,... - let finalIndex = match lastOption with - | Some b -> b // here b>=0, a valid end value. - | None -> unreachable // run "forever", well as far as Int32.MaxValue since indexing with a bounded type. - // The Current value for a valid index is "f i". - // Lazy<_> values are used as caches, to store either the result or an exception if thrown. - // These "Lazy<_>" caches are created only on the first call to current and forced immediately. - // The lazy creation of the cache nodes means enumerations that skip many Current values are not delayed by GC. - // For example, the full enumeration of Seq.initInfinite in the tests. - // state - let index = ref unstarted - // a Lazy node to cache the result/exception - let current = ref (Unchecked.defaultof<_>) - let setIndex i = index := i; current := (Unchecked.defaultof<_>) // cache node unprimed, initialised on demand. - let getCurrent() = - if !index = unstarted then notStarted() - if !index = completed then alreadyFinished() - match box !current with - | null -> current := Lazy<_>.Create(fun () -> f !index) - | _ -> () - // forced or re-forced immediately. - (!current).Force() - { new IEnumerator<'U> with - member x.Current = getCurrent() - interface IEnumerator with - member x.Current = box (getCurrent()) - member x.MoveNext() = - if !index = completed then - false - elif !index = unstarted then - setIndex 0 - true - else ( - if !index = System.Int32.MaxValue then raise <| System.InvalidOperationException (SR.GetString(SR.enumerationPastIntMaxValue)) - if !index = finalIndex then - false - else - setIndex (!index + 1) - true - ) - member self.Reset() = noReset() - interface System.IDisposable with - member x.Dispose() = () } - - let readAndClear r = - lock r (fun () -> match !r with None -> None | Some _ as res -> r := None; res) - - let generateWhileSome openf compute closef : IEnumerator<'U> = - let started = ref false - let curr = ref None - let state = ref (Some(openf())) - let getCurr() = - check !started - match !curr with None -> alreadyFinished() | Some x -> x - let start() = if not !started then (started := true) - - let dispose() = readAndClear state |> Option.iter closef - let finish() = (try dispose() finally curr := None) - { new IEnumerator<'U> with - member x.Current = getCurr() - interface IEnumerator with - member x.Current = box (getCurr()) - member x.MoveNext() = - start() - match !state with - | None -> false (* we started, then reached the end, then got another MoveNext *) - | Some s -> - match (try compute s with e -> finish(); reraise()) with - | None -> finish(); false - | Some _ as x -> curr := x; true - - member x.Reset() = noReset() - interface System.IDisposable with - member x.Dispose() = dispose() } - - [] - type ArrayEnumerator<'T>(arr: 'T array) = - let mutable curr = -1 - let mutable len = arr.Length - member x.Get() = - if curr >= 0 then - if curr >= len then alreadyFinished() - else arr.[curr] - else - notStarted() - interface IEnumerator<'T> with - member x.Current = x.Get() - interface System.Collections.IEnumerator with - member x.MoveNext() = - if curr >= len then false - else - curr <- curr + 1 - (curr < len) - member x.Current = box(x.Get()) - member x.Reset() = noReset() - interface System.IDisposable with - member x.Dispose() = () - - let ofArray arr = (new ArrayEnumerator<'T>(arr) :> IEnumerator<'T>) - - [] - type Singleton<'T>(v:'T) = - let mutable started = false - interface IEnumerator<'T> with - member x.Current = v - interface IEnumerator with - member x.Current = box v - member x.MoveNext() = if started then false else (started <- true; true) - member x.Reset() = noReset() - interface System.IDisposable with - member x.Dispose() = () - - let Singleton x = (new Singleton<'T>(x) :> IEnumerator<'T>) - - let EnumerateThenFinally f (e : IEnumerator<'T>) = - { new IEnumerator<'T> with - member x.Current = e.Current - interface IEnumerator with - member x.Current = (e :> IEnumerator).Current - member x.MoveNext() = e.MoveNext() - member x.Reset() = noReset() - interface System.IDisposable with - member x.Dispose() = - try - e.Dispose() - finally - f() - } - - // Use generators for some implementations of IEnumerables. - // - module Generator = - - open System.Collections - open System.Collections.Generic - - [] - type Step<'T> = - | Stop - | Yield of 'T - | Goto of Generator<'T> - - and Generator<'T> = - abstract Apply: (unit -> Step<'T>) - abstract Disposer: (unit -> unit) option - - let disposeG (g:Generator<'T>) = - match g.Disposer with - | None -> () - | Some f -> f() - - let appG (g:Generator<_>) = - //System.Console.WriteLine("{0}.appG", box g) - let res = g.Apply() - match res with - | Goto(next) -> - Goto(next) - | Yield _ -> - res - | Stop -> - //System.Console.WriteLine("appG: Stop") - disposeG g - res - - // Binding. - // - // We use a type definition to apply a local dynamic optimization. - // We automatically right-associate binding, i.e. push the continuations to the right. - // That is, bindG (bindG G1 cont1) cont2 --> bindG G1 (cont1 o cont2) - // This makes constructs such as the following linear rather than quadratic: - // - // let rec rwalk n = { if n > 0 then - // yield! rwalk (n-1) - // yield n } - - type GenerateThen<'T>(g:Generator<'T>, cont : unit -> Generator<'T>) = - member self.Generator = g - member self.Cont = cont - interface Generator<'T> with - member x.Apply = (fun () -> - match appG g with - | Stop -> - // OK, move onto the generator given by the continuation - Goto(cont()) - - | Yield _ as res -> - res - - | Goto next -> - Goto(GenerateThen<_>.Bind(next,cont))) - member x.Disposer = - g.Disposer - - - static member Bind (g:Generator<'T>, cont) = - match g with - | :? GenerateThen<'T> as g -> GenerateThen<_>.Bind(g.Generator,(fun () -> GenerateThen<_>.Bind (g.Cont(), cont))) - | g -> (new GenerateThen<'T>(g, cont) :> Generator<'T>) - - - let bindG g cont = GenerateThen<_>.Bind(g,cont) - - - // Internal type. Drive an underlying generator. Crucially when the generator returns - // a new generator we simply update our current generator and continue. Thus the enumerator - // effectively acts as a reference cell holding the current generator. This means that - // infinite or large generation chains (e.g. caused by long sequences of append's, including - // possible delay loops) can be referenced via a single enumerator. - // - // A classic case where this arises in this sort of sequence expression: - // let rec data s = { yield s; - // yield! data (s + random()) } - // - // This translates to - // let rec data s = Seq.delay (fun () -> Seq.append (Seq.singleton s) (Seq.delay (fun () -> data (s+random())))) - // - // When you unwind through all the Seq, IEnumerator and Generator objects created, - // you get (data s).GetEnumerator being an "GenerateFromEnumerator(EnumeratorWrappingLazyGenerator(...))" for the append. - // After one element is yielded, we move on to the generator for the inner delay, which in turn - // comes back to be a "GenerateFromEnumerator(EnumeratorWrappingLazyGenerator(...))". - // - // Defined as a type so we can optimize Enumerator/Generator chains in enumerateFromLazyGenerator - // and GenerateFromEnumerator. - - [] - type EnumeratorWrappingLazyGenerator<'T>(g:Generator<'T>) = - let mutable g = g - let mutable curr = None - let mutable finished = false - member e.Generator = g - interface IEnumerator<'T> with - member x.Current= match curr with Some(v) -> v | None -> raise <| System.InvalidOperationException (SR.GetString(SR.moveNextNotCalledOrFinished)) - interface System.Collections.IEnumerator with - member x.Current = box (x :> IEnumerator<_>).Current - member x.MoveNext() = - not finished && - (match appG g with - | Stop -> - curr <- None - finished <- true - false - | Yield(v) -> - curr <- Some(v) - true - | Goto(next) -> - (g <- next) - (x :> IEnumerator).MoveNext()) - member x.Reset() = IEnumerator.noReset() - interface System.IDisposable with - member x.Dispose() = - if not finished then disposeG g - - // Internal type, used to optimize Enumerator/Generator chains - type LazyGeneratorWrappingEnumerator<'T>(e:System.Collections.Generic.IEnumerator<'T>) = - member g.Enumerator = e - interface Generator<'T> with - member g.Apply = (fun () -> - if e.MoveNext() then - Yield(e.Current) - else - Stop) - member g.Disposer= Some(e.Dispose) - - let EnumerateFromGenerator(g:Generator<'T>) = - match g with - | :? LazyGeneratorWrappingEnumerator<'T> as g -> g.Enumerator - | _ -> (new EnumeratorWrappingLazyGenerator<_>(g) :> System.Collections.Generic.IEnumerator<_>) - - let GenerateFromEnumerator (e:System.Collections.Generic.IEnumerator<'T>) = - match e with - | :? EnumeratorWrappingLazyGenerator<'T> as e -> e.Generator - | _ -> (new LazyGeneratorWrappingEnumerator<'T>(e) :> Generator<'T>) - -namespace Microsoft.FSharp.Core.CompilerServices - - open System - open System.Diagnostics - open Microsoft.FSharp.Core - open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators - open Microsoft.FSharp.Core.Operators - open Microsoft.FSharp.Control - open Microsoft.FSharp.Collections - open Microsoft.FSharp.Primitives.Basics - open System.Collections - open System.Collections.Generic - - module RuntimeHelpers = - - [] - type internal StructBox<'T when 'T : equality>(value:'T) = - member x.Value = value - static member Comparer = - let gcomparer = HashIdentity.Structural<'T> - { new IEqualityComparer> with - member __.GetHashCode(v) = gcomparer.GetHashCode(v.Value) - member __.Equals(v1,v2) = gcomparer.Equals(v1.Value,v2.Value) } - - let inline checkNonNull argName arg = - match box arg with - | null -> nullArg argName - | _ -> () - - let mkSeq f = - { new IEnumerable<'U> with - member x.GetEnumerator() = f() - interface IEnumerable with - member x.GetEnumerator() = (f() :> IEnumerator) } - - [] - type EmptyEnumerable<'T> = - | EmptyEnumerable - interface IEnumerable<'T> with - member x.GetEnumerator() = IEnumerator.Empty<'T>() - interface IEnumerable with - member x.GetEnumerator() = (IEnumerator.Empty<'T>() :> IEnumerator) - - let Generate openf compute closef = - mkSeq (fun () -> IEnumerator.generateWhileSome openf compute closef) - - let GenerateUsing (openf : unit -> ('U :> System.IDisposable)) compute = - Generate openf compute (fun (s:'U) -> s.Dispose()) - - let EnumerateFromFunctions opener moveNext current = - Generate - opener - (fun x -> if moveNext x then Some(current x) else None) - (fun x -> match box(x) with :? System.IDisposable as id -> id.Dispose() | _ -> ()) - - // A family of enumerators that can have additional 'finally' actions added to the enumerator through - // the use of mutation. This is used to 'push' the disposal action for a 'use' into the next enumerator. - // For example, - // seq { use x = ... - // while ... } - // results in the 'while' loop giving an adjustable enumerator. This is then adjusted by adding the disposal action - // from the 'use' into the enumerator. This means that we avoid constructing a two-deep enumerator chain in this - // common case. - type IFinallyEnumerator = - abstract AppendFinallyAction : (unit -> unit) -> unit - - /// A concrete implementation of IEnumerable that adds the given compensation to the "Dispose" chain of any - /// enumerators returned by the enumerable. - [] - type FinallyEnumerable<'T>(compensation: unit -> unit, restf: unit -> seq<'T>) = - interface IEnumerable<'T> with - member x.GetEnumerator() = - try - let ie = restf().GetEnumerator() - match ie with - | :? IFinallyEnumerator as a -> - a.AppendFinallyAction(compensation) - ie - | _ -> - IEnumerator.EnumerateThenFinally compensation ie - with e -> - compensation() - reraise() - interface IEnumerable with - member x.GetEnumerator() = ((x :> IEnumerable<'T>).GetEnumerator() :> IEnumerator) - - /// An optimized object for concatenating a sequence of enumerables - [] - type ConcatEnumerator<'T,'U when 'U :> seq<'T>>(sources: seq<'U>) = - let mutable outerEnum = sources.GetEnumerator() - let mutable currInnerEnum = IEnumerator.Empty() - - let mutable started = false - let mutable finished = false - let mutable compensations = [] - - [] // false = unchecked - val mutable private currElement : 'T - - member x.Finish() = - finished <- true - try - match currInnerEnum with - | null -> () - | _ -> - try - currInnerEnum.Dispose() - finally - currInnerEnum <- null - finally - try - match outerEnum with - | null -> () - | _ -> - try - outerEnum.Dispose() - finally - outerEnum <- null - finally - let rec iter comps = - match comps with - | [] -> () - | h::t -> - try h() finally iter t - try - compensations |> List.rev |> iter - finally - compensations <- [] - - member x.GetCurrent() = - IEnumerator.check started - if finished then IEnumerator.alreadyFinished() else x.currElement - - interface IFinallyEnumerator with - member x.AppendFinallyAction(f) = - compensations <- f :: compensations - - interface IEnumerator<'T> with - member x.Current = x.GetCurrent() - - interface IEnumerator with - member x.Current = box (x.GetCurrent()) - - member x.MoveNext() = - if not started then (started <- true) - if finished then false - else - let rec takeInner () = - // check the inner list - if currInnerEnum.MoveNext() then - x.currElement <- currInnerEnum.Current - true - else - // check the outer list - let rec takeOuter() = - if outerEnum.MoveNext() then - let ie = outerEnum.Current - // Optimization to detect the statically-allocated empty IEnumerables - match box ie with - | :? EmptyEnumerable<'T> -> - // This one is empty, just skip, don't call GetEnumerator, try again - takeOuter() - | _ -> - // OK, this one may not be empty. - // Don't forget to dispose of the enumerator for the inner list now we're done with it - currInnerEnum.Dispose() - currInnerEnum <- ie.GetEnumerator() - takeInner () - else - // We're done - x.Finish() - false - takeOuter() - takeInner () - - member x.Reset() = IEnumerator.noReset() - - interface System.IDisposable with - member x.Dispose() = - if not finished then - x.Finish() - - let EnumerateUsing (resource : 'T :> System.IDisposable) (rest: 'T -> #seq<'U>) = - (FinallyEnumerable((fun () -> match box resource with null -> () | _ -> resource.Dispose()), - (fun () -> rest resource :> seq<_>)) :> seq<_>) - - let mkConcatSeq (sources: seq<'U :> seq<'T>>) = - mkSeq (fun () -> new ConcatEnumerator<_,_>(sources) :> IEnumerator<'T>) - - let EnumerateWhile (g : unit -> bool) (b: seq<'T>) : seq<'T> = - let started = ref false - let curr = ref None - let getCurr() = - IEnumerator.check !started - match !curr with None -> IEnumerator.alreadyFinished() | Some x -> x - let start() = if not !started then (started := true) - - let finish() = (curr := None) - mkConcatSeq - (mkSeq (fun () -> - { new IEnumerator<_> with - member x.Current = getCurr() - interface IEnumerator with - member x.Current = box (getCurr()) - member x.MoveNext() = - start() - let keepGoing = (try g() with e -> finish (); reraise ()) in - if keepGoing then - curr := Some(b); true - else - finish(); false - member x.Reset() = IEnumerator.noReset() - interface System.IDisposable with - member x.Dispose() = () })) - - let EnumerateThenFinally (rest : seq<'T>) (compensation : unit -> unit) = - (FinallyEnumerable(compensation, (fun () -> rest)) :> seq<_>) - - let CreateEvent (add : 'Delegate -> unit) (remove : 'Delegate -> unit) (create : (obj -> 'Args -> unit) -> 'Delegate ) :IEvent<'Delegate,'Args> = - // Note, we implement each interface explicitly: this works around a bug in the CLR - // implementation on CompactFramework 3.7, used on Windows Phone 7 - { new obj() with - member x.ToString() = "" - interface IEvent<'Delegate,'Args> - interface IDelegateEvent<'Delegate> with - member x.AddHandler(h) = add h - member x.RemoveHandler(h) = remove h - interface System.IObservable<'Args> with - member x.Subscribe(r:IObserver<'Args>) = - let h = create (fun _ args -> r.OnNext(args)) - add h - { new System.IDisposable with - member x.Dispose() = remove h } } - - - [] - type GeneratedSequenceBase<'T>() = - let mutable redirectTo : GeneratedSequenceBase<'T> = Unchecked.defaultof<_> - let mutable redirect : bool = false - - abstract GetFreshEnumerator : unit -> IEnumerator<'T> - abstract GenerateNext : next:byref> -> int // 0 = Stop, 1 = Yield, 2 = Goto - abstract Close: unit -> unit - abstract CheckClose: bool - abstract LastGenerated : 'T - - //[] - member x.MoveNextImpl() = - let active = - if redirect then redirectTo - else x - let mutable target = null - match active.GenerateNext(&target) with - | 1 -> - true - | 2 -> - match target.GetEnumerator() with - | :? GeneratedSequenceBase<'T> as g when not active.CheckClose -> - redirectTo <- g - | e -> - redirectTo <- - { new GeneratedSequenceBase<'T>() with - member x.GetFreshEnumerator() = e - member x.GenerateNext(_) = if e.MoveNext() then 1 else 0 - member x.Close() = try e.Dispose() finally active.Close() - member x.CheckClose = true - member x.LastGenerated = e.Current } - redirect <- true - x.MoveNextImpl() - | _ (* 0 *) -> - false - - interface IEnumerable<'T> with - member x.GetEnumerator() = x.GetFreshEnumerator() - interface IEnumerable with - member x.GetEnumerator() = (x.GetFreshEnumerator() :> IEnumerator) - interface IEnumerator<'T> with - member x.Current = if redirect then redirectTo.LastGenerated else x.LastGenerated - member x.Dispose() = if redirect then redirectTo.Close() else x.Close() - interface IEnumerator with - member x.Current = box (if redirect then redirectTo.LastGenerated else x.LastGenerated) - - //[] - member x.MoveNext() = x.MoveNextImpl() - - member x.Reset() = raise <| new System.NotSupportedException() - - namespace Microsoft.FSharp.Collections open System @@ -827,7 +13,15 @@ namespace Microsoft.FSharp.Collections open Microsoft.FSharp.Core.CompilerServices open Microsoft.FSharp.Control open Microsoft.FSharp.Collections + open Microsoft.FSharp.Collections.Composer + open Microsoft.FSharp.Collections.Composer.Core open Microsoft.FSharp.Primitives.Basics + open Microsoft.FSharp.Collections.IEnumerator + + module Upcast = + // The f# compiler outputs unnecessary unbox.any calls in upcasts. If this functionality + // is fixed with the compiler then these functions can be removed. + let inline enumerable (t:#IEnumerable<'T>) : IEnumerable<'T> = (# "" t : IEnumerable<'T> #) [] type CachedSeq<'T>(cleanup,res:seq<'T>) = @@ -843,118 +37,103 @@ namespace Microsoft.FSharp.Collections [] [] module Seq = - #if FX_NO_ICLONEABLE open Microsoft.FSharp.Core.ICloneableExtensions #else #endif - - open Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers - let mkDelayedSeq (f: unit -> IEnumerable<'T>) = mkSeq (fun () -> f().GetEnumerator()) - let mkUnfoldSeq f x = mkSeq (fun () -> IEnumerator.unfold f x) let inline indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException(SR.GetString(SR.keyNotFoundAlt))) + [] + let toComposer (source:seq<'T>): Composer.Core.ISeq<'T> = + checkNonNull "source" source + Composer.ofSeq source + + let toComposer' name (source:seq<'T>): Composer.Core.ISeq<'T> = + checkNonNull name source + Composer.ofSeq source + [] let delay f = mkDelayedSeq f [] - let unfold f x = mkUnfoldSeq f x + let unfold (generator:'State->option<'T * 'State>) (state:'State) : seq<'T> = + Composer.unfold generator state + |> Upcast.enumerable [] let empty<'T> = (EmptyEnumerable :> seq<'T>) [] - let initInfinite f = mkSeq (fun () -> IEnumerator.upto None f) + let initInfinite<'T> (f:int->'T) : IEnumerable<'T> = + Composer.initInfinite f + |> Upcast.enumerable [] - let init count f = - if count < 0 then invalidArgInputMustBeNonNegative "count" count - mkSeq (fun () -> IEnumerator.upto (Some (count-1)) f) + let init<'T> (count:int) (f:int->'T) : IEnumerable<'T> = + Composer.init count f + |> Upcast.enumerable [] let iter f (source : seq<'T>) = - checkNonNull "source" source - use e = source.GetEnumerator() - while e.MoveNext() do - f e.Current + source |> toComposer |> Composer.iter f + + [] + let tryHead (source : seq<_>) = + source |> toComposer |> Composer.tryHead + + [] + let skip count (source: seq<_>) = + source |> toComposer + |> Composer.skip count |> Upcast.enumerable + + let invalidArgumnetIndex = invalidArgFmt "index" [] let item i (source : seq<'T>) = - checkNonNull "source" source - if i < 0 then invalidArgInputMustBeNonNegative "index" i - use e = source.GetEnumerator() - IEnumerator.nth i e + if i < 0 then invalidArgInputMustBeNonNegative "index" i else + source + |> toComposer |> Composer.skip i |> Upcast.enumerable + |> tryHead + |> function + | None -> invalidArgFmt "index" "{0}\nseq was short by 1 element" [|SR.GetString SR.notEnoughElements|] + | Some value -> value [] - let tryItem i (source : seq<'T>) = - checkNonNull "source" source - if i < 0 then None else - use e = source.GetEnumerator() - IEnumerator.tryItem i e + let tryItem i (source:seq<'T>) = + source |> toComposer |> Composer.tryItem i - [] + [] let nth i (source : seq<'T>) = item i source - [] - let iteri f (source : seq<'T>) = - checkNonNull "source" source - use e = source.GetEnumerator() - let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let mutable i = 0 - while e.MoveNext() do - f.Invoke(i, e.Current) - i <- i + 1 - - [] - let exists f (source : seq<'T>) = - checkNonNull "source" source - use e = source.GetEnumerator() - let mutable state = false - while (not state && e.MoveNext()) do - state <- f e.Current - state + [] + let iteri f (source:seq<'T>) = + let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt f + source |> toComposer |> Composer.iteri (fun idx a -> f.Invoke(idx,a)) - [] - let inline contains element (source : seq<'T>) = - checkNonNull "source" source - use e = source.GetEnumerator() - let mutable state = false - while (not state && e.MoveNext()) do - state <- element = e.Current - state + [] + let exists f (source:seq<'T>) = + source |> toComposer |> Composer.exists f - [] - let forall f (source : seq<'T>) = - checkNonNull "source" source - use e = source.GetEnumerator() - let mutable state = true - while (state && e.MoveNext()) do - state <- f e.Current - state + [] + let inline contains element (source:seq<'T>) = + source |> toComposer |> Composer.contains element + [] + let forall f (source:seq<'T>) = + source |> toComposer |> Composer.forall f - [] - let iter2 f (source1 : seq<_>) (source2 : seq<_>) = - checkNonNull "source1" source1 - checkNonNull "source2" source2 - use e1 = source1.GetEnumerator() - use e2 = source2.GetEnumerator() + [] + let iter2 (f:'T->'U->unit) (source1 : seq<'T>) (source2 : seq<'U>) = let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - while (e1.MoveNext() && e2.MoveNext()) do - f.Invoke(e1.Current, e2.Current) + (source1 |> toComposer' "source1", source2 |> toComposer' "source2") + ||> Composer.iter2 (fun a b -> f.Invoke(a,b)) - [] - let iteri2 f (source1 : seq<_>) (source2 : seq<_>) = - checkNonNull "source1" source1 - checkNonNull "source2" source2 - use e1 = source1.GetEnumerator() - use e2 = source2.GetEnumerator() + [] + let iteri2 (f:int->'T->'U->unit) (source1 : seq<_>) (source2 : seq<_>) = let f = OptimizedClosures.FSharpFunc<_,_,_,_>.Adapt(f) - let mutable i = 0 - while (e1.MoveNext() && e2.MoveNext()) do - f.Invoke(i, e1.Current, e2.Current) - i <- i + 1 + (source1 |> toComposer' "source1", source2 |> toComposer' "source2") + ||> Composer.iteri2 (fun idx a b -> f.Invoke(idx,a,b)) // Build an IEnumerble by wrapping/transforming iterators as they get generated. let revamp f (ie : seq<_>) = mkSeq (fun () -> f (ie.GetEnumerator())) @@ -964,63 +143,51 @@ namespace Microsoft.FSharp.Collections mkSeq (fun () -> f (ie1.GetEnumerator()) (source2.GetEnumerator()) (source3.GetEnumerator())) [] - let filter f source = - checkNonNull "source" source - revamp (IEnumerator.filter f) source + let filter<'T> (f:'T->bool) (source:seq<'T>) : seq<'T> = + source |> toComposer |> Composer.filter f |> Upcast.enumerable [] - let where f source = filter f source + let where f source = filter f source - [] - let map f source = - checkNonNull "source" source - revamp (IEnumerator.map f) source + [] + let map<'T,'U> (f:'T->'U) (source:seq<'T>) : seq<'U> = + source |> toComposer |> Composer.map f |> Upcast.enumerable - [] - let mapi f source = - checkNonNull "source" source - revamp (IEnumerator.mapi f) source + [] + let mapi f source = + let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt f + source |> toComposer |> Composer.mapi (fun idx a ->f.Invoke(idx,a)) |> Upcast.enumerable - [] - let mapi2 f source1 source2 = - checkNonNull "source1" source1 - checkNonNull "source2" source2 - revamp2 (IEnumerator.mapi2 f) source1 source2 + [] + let mapi2 (mapfn:int->'T->'U->'V) (source1:seq<'T>) (source2:seq<'U>) = + let f = OptimizedClosures.FSharpFunc.Adapt mapfn + (source1 |> toComposer' "source1", source2 |> toComposer' "source2") + ||> Composer.mapi2 (fun idx a b ->f.Invoke(idx,a,b)) |> Upcast.enumerable - [] - let map2 f source1 source2 = - checkNonNull "source1" source1 - checkNonNull "source2" source2 - revamp2 (IEnumerator.map2 f) source1 source2 + [] + let map2<'T,'U,'V> (mapfn:'T->'U->'V) (source1:seq<'T>) (source2:seq<'U>) : seq<'V> = + (source1 |> toComposer' "source1", source2 |> toComposer' "source2") + ||> Composer.map2 mapfn |> Upcast.enumerable - [] - let map3 f source1 source2 source3 = - checkNonNull "source1" source1 - checkNonNull "source2" source2 - checkNonNull "source3" source3 - revamp3 (IEnumerator.map3 f) source1 source2 source3 + [] + let map3 mapfn source1 source2 source3 = + (source1 |> toComposer' "source1", source2 |> toComposer' "source2", source3 |> toComposer' "source3") + |||> Composer.map3 mapfn |> Upcast.enumerable [] - let choose f source = - checkNonNull "source" source - revamp (IEnumerator.choose f) source + let choose f source = + source |> toComposer |> Composer.choose f |> Upcast.enumerable [] let indexed source = - checkNonNull "source" source - mapi (fun i x -> i,x) source + source |> toComposer |> Composer.indexed |> Upcast.enumerable [] let zip source1 source2 = - checkNonNull "source1" source1 - checkNonNull "source2" source2 map2 (fun x y -> x,y) source1 source2 [] let zip3 source1 source2 source3 = - checkNonNull "source1" source1 - checkNonNull "source2" source2 - checkNonNull "source3" source3 map2 (fun x (y,z) -> x,y,z) source1 (zip source2 source3) [] @@ -1030,49 +197,30 @@ namespace Microsoft.FSharp.Collections [] let tryPick f (source : seq<'T>) = - checkNonNull "source" source - use e = source.GetEnumerator() - let mutable res = None - while (Option.isNone res && e.MoveNext()) do - res <- f e.Current - res + source |> toComposer |> Composer.tryPick f [] let pick f source = - checkNonNull "source" source match tryPick f source with | None -> indexNotFound() | Some x -> x [] let tryFind f (source : seq<'T>) = - checkNonNull "source" source - use e = source.GetEnumerator() - let mutable res = None - while (Option.isNone res && e.MoveNext()) do - let c = e.Current - if f c then res <- Some(c) - res + source |> toComposer |> Composer.tryFind f [] let find f source = - checkNonNull "source" source match tryFind f source with | None -> indexNotFound() | Some x -> x [] let take count (source : seq<'T>) = - checkNonNull "source" source if count < 0 then invalidArgInputMustBeNonNegative "count" count (* Note: don't create or dispose any IEnumerable if n = 0 *) if count = 0 then empty else - seq { use e = source.GetEnumerator() - for x in 0 .. count - 1 do - if not (e.MoveNext()) then - invalidOpFmt "tried to take {0} {1} past the end of the seq" - [|SR.GetString SR.notEnoughElements; x; (if x=1 then "element" else "elements")|] - yield e.Current } + source |> toComposer |> Composer.take count |> Upcast.enumerable [] let isEmpty (source : seq<'T>) = @@ -1085,11 +233,9 @@ namespace Microsoft.FSharp.Collections use ie = source.GetEnumerator() not (ie.MoveNext()) - [] - let concat sources = - checkNonNull "sources" sources - mkConcatSeq sources + let concat (sources:seq<#seq<'T>>) : seq<'T> = + sources |> toComposer' "sources" |> Composer.map toComposer |> Composer.concat |> Upcast.enumerable [] let length (source : seq<'T>) = @@ -1105,78 +251,46 @@ namespace Microsoft.FSharp.Collections state <- state + 1 state - [] - let fold<'T,'State> f (x:'State) (source : seq<'T>) = - checkNonNull "source" source - use e = source.GetEnumerator() + [] + let fold<'T,'State> (f:'State->'T->'State) (x:'State) (source:seq<'T>) = let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let mutable state = x - while e.MoveNext() do - state <- f.Invoke(state, e.Current) - state - - [] - let fold2<'T1,'T2,'State> f (state:'State) (source1: seq<'T1>) (source2: seq<'T2>) = - checkNonNull "source1" source1 - checkNonNull "source2" source2 + source |> toComposer + |> Composer.fold<'T,'State>(fun (a:'State) (b:'T) -> f.Invoke(a,b)) x - use e1 = source1.GetEnumerator() - use e2 = source2.GetEnumerator() + [] + let fold2<'T1,'T2,'State> f (state:'State) (source1: seq<'T1>) (source2: seq<'T2>) = let f = OptimizedClosures.FSharpFunc<_,_,_,_>.Adapt(f) + (source1 |> toComposer' "source1", source2 |> toComposer' "source2") + ||> Composer.fold2(fun s a b -> f.Invoke(s,a,b)) state - let mutable state = state - while e1.MoveNext() && e2.MoveNext() do - state <- f.Invoke(state, e1.Current, e2.Current) - - state - - [] + [] let reduce f (source : seq<'T>) = - checkNonNull "source" source - use e = source.GetEnumerator() - if not (e.MoveNext()) then invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let mutable state = e.Current - while e.MoveNext() do - state <- f.Invoke(state, e.Current) - state - - let fromGenerator f = mkSeq(fun () -> Generator.EnumerateFromGenerator (f())) - let toGenerator (ie : seq<_>) = Generator.GenerateFromEnumerator (ie.GetEnumerator()) + source |> toComposer |> Composer.reduce(fun a b -> f.Invoke(a,b)) [] let replicate count x = + #if FX_ATLEAST_40 System.Linq.Enumerable.Repeat(x,count) + #else + if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative)) + seq { for _ in 1 .. count -> x } + #endif [] let append (source1: seq<'T>) (source2: seq<'T>) = - checkNonNull "source1" source1 - checkNonNull "source2" source2 - fromGenerator(fun () -> Generator.bindG (toGenerator source1) (fun () -> toGenerator source2)) - + (source1 |> toComposer' "source1", source2 |> toComposer' "source2") + ||> Composer.append |> Upcast.enumerable [] let collect f sources = map f sources |> concat - [] + [] let compareWith (f:'T -> 'T -> int) (source1 : seq<'T>) (source2: seq<'T>) = - checkNonNull "source1" source1 - checkNonNull "source2" source2 - use e1 = source1.GetEnumerator() - use e2 = source2.GetEnumerator() let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let rec go () = - let e1ok = e1.MoveNext() - let e2ok = e2.MoveNext() - let c = if e1ok = e2ok then 0 else if e1ok then 1 else -1 - if c <> 0 then c else - if not e1ok || not e2ok then 0 - else - let c = f.Invoke(e1.Current, e2.Current) - if c <> 0 then c else - go () - go() + (source1 |> toComposer' "source1", source2 |> toComposer' "source2") + ||> Composer.compareWith (fun a b -> f.Invoke(a,b)) [] let ofList (source : 'T list) = @@ -1191,23 +305,11 @@ namespace Microsoft.FSharp.Collections [] let ofArray (source : 'T array) = checkNonNull "source" source - mkSeq (fun () -> IEnumerator.ofArray source) + Upcast.enumerable (Composer.ofArray source) [] let toArray (source : seq<'T>) = - checkNonNull "source" source - match source with - | :? ('T[]) as res -> (res.Clone() :?> 'T[]) - | :? ('T list) as res -> List.toArray res - | :? ICollection<'T> as res -> - // Directly create an array and copy ourselves. - // This avoids an extra copy if using ResizeArray in fallback below. - let arr = Array.zeroCreateUnchecked res.Count - res.CopyTo(arr, 0) - arr - | _ -> - let res = ResizeArray<_>(source) - res.ToArray() + source |> toComposer |> Composer.toArray let foldArraySubRight (f:OptimizedClosures.FSharpFunc<'T,_,_>) (arr: 'T[]) start fin acc = let mutable state = acc @@ -1242,36 +344,18 @@ namespace Microsoft.FSharp.Collections let singleton x = mkSeq (fun () -> IEnumerator.Singleton x) - [] + [] let truncate n (source: seq<'T>) = - checkNonNull "source" source - seq { let i = ref 0 - use ie = source.GetEnumerator() - while !i < n && ie.MoveNext() do - i := !i + 1 - yield ie.Current } - - [] - let pairwise (source: seq<'T>) = - checkNonNull "source" source - seq { use ie = source.GetEnumerator() - if ie.MoveNext() then - let iref = ref ie.Current - while ie.MoveNext() do - let j = ie.Current - yield (!iref, j) - iref := j } - - [] - let scan<'T,'State> f (z:'State) (source : seq<'T>) = - checkNonNull "source" source - let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - seq { let zref = ref z - yield !zref - use ie = source.GetEnumerator() - while ie.MoveNext() do - zref := f.Invoke(!zref, ie.Current) - yield !zref } + if n <= 0 then empty else + source |> toComposer |> Composer.truncate n |> Upcast.enumerable + + [] + let pairwise<'T> (source:seq<'T>) : seq<'T*'T> = + source |> toComposer |> Composer.pairwise |> Upcast.enumerable + + [] + let scan<'T,'State> (folder:'State->'T->'State) (state:'State) (source:seq<'T>) : seq<'State> = + source |> toComposer |> Composer.scan folder state |> Upcast.enumerable [] let tryFindBack f (source : seq<'T>) = @@ -1291,31 +375,15 @@ namespace Microsoft.FSharp.Collections let res = Array.scanSubRight f arr 0 (arr.Length - 1) acc res :> seq<_>) + [] + let tryFindIndex p (source:seq<_>) = + source |> toComposer |> Composer.tryFindIndex p + [] let findIndex p (source:seq<_>) = - checkNonNull "source" source - use ie = source.GetEnumerator() - let rec loop i = - if ie.MoveNext() then - if p ie.Current then - i - else loop (i+1) - else - indexNotFound() - loop 0 - - [] - let tryFindIndex p (source:seq<_>) = - checkNonNull "source" source - use ie = source.GetEnumerator() - let rec loop i = - if ie.MoveNext() then - if p ie.Current then - Some i - else loop (i+1) - else - None - loop 0 + match tryFindIndex p source with + | None -> indexNotFound() + | Some x -> x [] let tryFindIndexBack f (source : seq<'T>) = @@ -1330,27 +398,9 @@ namespace Microsoft.FSharp.Collections // windowed : int -> seq<'T> -> seq<'T[]> [] let windowed windowSize (source: seq<_>) = - checkNonNull "source" source if windowSize <= 0 then invalidArgFmt "windowSize" "{0}\nwindowSize = {1}" [|SR.GetString SR.inputMustBePositive; windowSize|] - seq { - let arr = Array.zeroCreateUnchecked windowSize - let r = ref (windowSize - 1) - let i = ref 0 - use e = source.GetEnumerator() - while e.MoveNext() do - arr.[!i] <- e.Current - i := (!i + 1) % windowSize - if !r = 0 then - if windowSize < 32 then - yield Array.init windowSize (fun j -> arr.[(!i+j) % windowSize]) - else - let result = Array.zeroCreateUnchecked windowSize - Array.Copy(arr, !i, result, 0, windowSize - !i) - Array.Copy(arr, 0, result, windowSize - !i, !i) - yield result - else r := (!r - 1) - } + source |> toComposer |> Composer.windowed windowSize |> Upcast.enumerable [] let cache (source : seq<'T>) = @@ -1421,90 +471,40 @@ namespace Microsoft.FSharp.Collections checkNonNull "source" source mkSeq (fun () -> source.GetEnumerator()) - let inline groupByImpl (comparer:IEqualityComparer<'SafeKey>) (keyf:'T->'SafeKey) (getKey:'SafeKey->'Key) (seq:seq<'T>) = - checkNonNull "seq" seq - - let dict = Dictionary<_,ResizeArray<_>> comparer - - // Previously this was 1, but I think this is rather stingy, considering that we are already paying - // for at least a key, the ResizeArray reference, which includes an array reference, an Entry in the - // Dictionary, plus any empty space in the Dictionary of unfilled hash buckets. - let minimumBucketSize = 4 - - // Build the groupings - seq |> iter (fun v -> - let safeKey = keyf v - let mutable prev = Unchecked.defaultof<_> - match dict.TryGetValue (safeKey, &prev) with - | true -> prev.Add v - | false -> - let prev = ResizeArray () - dict.[safeKey] <- prev - prev.Add v) - - // Trim the size of each result group, don't trim very small buckets, as excessive work, and garbage for - // minimal gain - dict |> iter (fun group -> if group.Value.Count > minimumBucketSize then group.Value.TrimExcess()) - - // Return the sequence-of-sequences. Don't reveal the - // internal collections: just reveal them as sequences - dict |> map (fun group -> (getKey group.Key, readonly group.Value)) - - // We avoid wrapping a StructBox, because under 64 JIT we get some "hard" tailcalls which affect performance - let groupByValueType (keyf:'T->'Key) (seq:seq<'T>) = seq |> groupByImpl HashIdentity.Structural<'Key> keyf id - - // Wrap a StructBox around all keys in case the key type is itself a type using null as a representation - let groupByRefType (keyf:'T->'Key) (seq:seq<'T>) = seq |> groupByImpl StructBox<'Key>.Comparer (fun t -> StructBox (keyf t)) (fun sb -> sb.Value) - [] - let groupBy (keyf:'T->'Key) (seq:seq<'T>) = + let groupBy (keyf:'T->'Key) (source:seq<'T>) = + let grouped = #if FX_RESHAPED_REFLECTION - if (typeof<'Key>).GetTypeInfo().IsValueType + if (typeof<'Key>).GetTypeInfo().IsValueType #else - if typeof<'Key>.IsValueType + if typeof<'Key>.IsValueType #endif - then mkDelayedSeq (fun () -> groupByValueType keyf seq) - else mkDelayedSeq (fun () -> groupByRefType keyf seq) + then source |> toComposer |> Composer.GroupBy.byVal keyf + else source |> toComposer |> Composer.GroupBy.byRef keyf + + grouped + |> Composer.map (fun (key,value) -> key, Upcast.enumerable value) + |> Upcast.enumerable [] let distinct source = - checkNonNull "source" source - seq { let hashSet = HashSet<'T>(HashIdentity.Structural<'T>) - for v in source do - if hashSet.Add(v) then - yield v } + source |> toComposer |> Composer.distinct |> Upcast.enumerable [] let distinctBy keyf source = - checkNonNull "source" source - seq { let hashSet = HashSet<_>(HashIdentity.Structural<_>) - for v in source do - if hashSet.Add(keyf v) then - yield v } + source |> toComposer |> Composer.distinctBy keyf |> Upcast.enumerable [] let sortBy keyf source = - checkNonNull "source" source - mkDelayedSeq (fun () -> - let array = source |> toArray - Array.stableSortInPlaceBy keyf array - array :> seq<_>) + source |> toComposer |> Composer.sortBy keyf |> Upcast.enumerable [] let sort source = - checkNonNull "source" source - mkDelayedSeq (fun () -> - let array = source |> toArray - Array.stableSortInPlace array - array :> seq<_>) + source |> toComposer |> Composer.sort |> Upcast.enumerable [] let sortWith f source = - checkNonNull "source" source - mkDelayedSeq (fun () -> - let array = source |> toArray - Array.stableSortInPlaceWith f array - array :> seq<_>) + source |> toComposer |> Composer.sortWith f |> Upcast.enumerable [] let inline sortByDescending keyf source = @@ -1518,303 +518,95 @@ namespace Microsoft.FSharp.Collections let inline compareDescending a b = compare b a sortWith compareDescending source - let inline countByImpl (comparer:IEqualityComparer<'SafeKey>) (keyf:'T->'SafeKey) (getKey:'SafeKey->'Key) (source:seq<'T>) = - checkNonNull "source" source - - let dict = Dictionary comparer - - // Build the groupings - source |> iter (fun v -> - let safeKey = keyf v - let mutable prev = Unchecked.defaultof<_> - if dict.TryGetValue(safeKey, &prev) - then dict.[safeKey] <- prev + 1 - else dict.[safeKey] <- 1) - - dict |> map (fun group -> (getKey group.Key, group.Value)) - - // We avoid wrapping a StructBox, because under 64 JIT we get some "hard" tailcalls which affect performance - let countByValueType (keyf:'T->'Key) (seq:seq<'T>) = seq |> countByImpl HashIdentity.Structural<'Key> keyf id - - // Wrap a StructBox around all keys in case the key type is itself a type using null as a representation - let countByRefType (keyf:'T->'Key) (seq:seq<'T>) = seq |> countByImpl StructBox<'Key>.Comparer (fun t -> StructBox (keyf t)) (fun sb -> sb.Value) - [] let countBy (keyf:'T->'Key) (source:seq<'T>) = - checkNonNull "source" source - #if FX_RESHAPED_REFLECTION if (typeof<'Key>).GetTypeInfo().IsValueType #else if typeof<'Key>.IsValueType #endif - then mkDelayedSeq (fun () -> countByValueType keyf source) - else mkDelayedSeq (fun () -> countByRefType keyf source) - - [] - let inline sum (source: seq< ^a>) : ^a = - use e = source.GetEnumerator() - let mutable acc = LanguagePrimitives.GenericZero< ^a> - while e.MoveNext() do - acc <- Checked.(+) acc e.Current - acc - - [] + then source |> toComposer |> Composer.CountBy.byVal keyf |> Upcast.enumerable + else source |> toComposer |> Composer.CountBy.byRef keyf |> Upcast.enumerable + + [] + let inline sum (source:seq<'a>) : 'a = + source |> toComposer |> Composer.sum + + [] let inline sumBy (f : 'T -> ^U) (source: seq<'T>) : ^U = - use e = source.GetEnumerator() - let mutable acc = LanguagePrimitives.GenericZero< ^U> - while e.MoveNext() do - acc <- Checked.(+) acc (f e.Current) - acc + source |> toComposer |> Composer.sumBy f - [] + [] let inline average (source: seq< ^a>) : ^a = - checkNonNull "source" source - use e = source.GetEnumerator() - let mutable acc = LanguagePrimitives.GenericZero< ^a> - let mutable count = 0 - while e.MoveNext() do - acc <- Checked.(+) acc e.Current - count <- count + 1 - if count = 0 then - invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString - LanguagePrimitives.DivideByInt< ^a> acc count - - [] + source |> toComposer |> Composer.average + + [] let inline averageBy (f : 'T -> ^U) (source: seq< 'T >) : ^U = - checkNonNull "source" source - use e = source.GetEnumerator() - let mutable acc = LanguagePrimitives.GenericZero< ^U> - let mutable count = 0 - while e.MoveNext() do - acc <- Checked.(+) acc (f e.Current) - count <- count + 1 - if count = 0 then - invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString - LanguagePrimitives.DivideByInt< ^U> acc count - - [] - let inline min (source: seq<_>) = - checkNonNull "source" source - use e = source.GetEnumerator() - if not (e.MoveNext()) then - invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString - let mutable acc = e.Current - while e.MoveNext() do - let curr = e.Current - if curr < acc then - acc <- curr - acc - - [] - let inline minBy (f : 'T -> 'U) (source: seq<'T>) : 'T = - checkNonNull "source" source - use e = source.GetEnumerator() - if not (e.MoveNext()) then - invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString - let first = e.Current - let mutable acc = f first - let mutable accv = first - while e.MoveNext() do - let currv = e.Current - let curr = f currv - if curr < acc then - acc <- curr - accv <- currv - accv - -(* - [] - let inline minValBy (f : 'T -> 'U) (source: seq<'T>) : 'U = - checkNonNull "source" source - use e = source.GetEnumerator() - if not (e.MoveNext()) then - invalidArg "source" InputSequenceEmptyString - let first = e.Current - let mutable acc = f first - while e.MoveNext() do - let currv = e.Current - let curr = f currv - if curr < acc then - acc <- curr - acc - -*) - [] - let inline max (source: seq<_>) = - checkNonNull "source" source - use e = source.GetEnumerator() - if not (e.MoveNext()) then - invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString - let mutable acc = e.Current - while e.MoveNext() do - let curr = e.Current - if curr > acc then - acc <- curr - acc - - [] - let inline maxBy (f : 'T -> 'U) (source: seq<'T>) : 'T = - checkNonNull "source" source - use e = source.GetEnumerator() - if not (e.MoveNext()) then - invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString - let first = e.Current - let mutable acc = f first - let mutable accv = first - while e.MoveNext() do - let currv = e.Current - let curr = f currv - if curr > acc then - acc <- curr - accv <- currv - accv - - -(* - [] - let inline maxValBy (f : 'T -> 'U) (source: seq<'T>) : 'U = - checkNonNull "source" source - use e = source.GetEnumerator() - if not (e.MoveNext()) then - invalidArg "source" InputSequenceEmptyString - let first = e.Current - let mutable acc = f first - while e.MoveNext() do - let currv = e.Current - let curr = f currv - if curr > acc then - acc <- curr - acc - -*) - [] - let takeWhile p (source: seq<_>) = - checkNonNull "source" source - seq { use e = source.GetEnumerator() - let latest = ref Unchecked.defaultof<_> - while e.MoveNext() && (latest := e.Current; p !latest) do - yield !latest } + source |> toComposer |> Composer.averageBy f - [] - let skip count (source: seq<_>) = - checkNonNull "source" source - seq { use e = source.GetEnumerator() - for x in 1 .. count do - if not (e.MoveNext()) then - invalidOpFmt "tried to skip {0} {1} past the end of the seq" - [|SR.GetString SR.notEnoughElements; x; (if x=1 then "element" else "elements")|] - while e.MoveNext() do - yield e.Current } + [] + let inline min (source: seq<'T>): 'T when 'T : comparison = + source |> toComposer |> Composer.min - [] - let skipWhile p (source: seq<_>) = - checkNonNull "source" source - seq { use e = source.GetEnumerator() - let latest = ref (Unchecked.defaultof<_>) - let ok = ref false - while e.MoveNext() do - if (latest := e.Current; (!ok || not (p !latest))) then - ok := true - yield !latest } + [] + let inline minBy (projection: 'T -> 'U when 'U:comparison) (source: seq<'T>) : 'T = + source |> toComposer |> Composer.minBy projection + [] + let inline max (source: seq<'T>) = + source |> toComposer |> Composer.max - [] - let forall2 p (source1: seq<_>) (source2: seq<_>) = - checkNonNull "source1" source1 - checkNonNull "source2" source2 - use e1 = source1.GetEnumerator() - use e2 = source2.GetEnumerator() - let p = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(p) - let mutable ok = true - while (ok && e1.MoveNext() && e2.MoveNext()) do - ok <- p.Invoke(e1.Current, e2.Current) - ok + [] + let inline maxBy (projection: 'T -> 'U) (source: seq<'T>) : 'T = + source |> toComposer |> Composer.maxBy projection + + [] + let takeWhile predicate (source: seq<_>) = + source |> toComposer |> Composer.takeWhile predicate |> Upcast.enumerable + [] + let skipWhile predicate (source: seq<_>) = + source |> toComposer |> Composer.skipWhile predicate |> Upcast.enumerable - [] + [] + let forall2 p (source1: seq<_>) (source2: seq<_>) = + let p = OptimizedClosures.FSharpFunc<_,_,_>.Adapt p + (source1 |> toComposer' "source1", source2 |> toComposer' "source2") + ||> Composer.forall2 (fun a b -> p.Invoke(a,b)) + + [] let exists2 p (source1: seq<_>) (source2: seq<_>) = - checkNonNull "source1" source1 - checkNonNull "source2" source2 - use e1 = source1.GetEnumerator() - use e2 = source2.GetEnumerator() - let p = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(p) - let mutable ok = false - while (not ok && e1.MoveNext() && e2.MoveNext()) do - ok <- p.Invoke(e1.Current, e2.Current) - ok - - [] - let head (source : seq<_>) = - checkNonNull "source" source - use e = source.GetEnumerator() - if (e.MoveNext()) then e.Current - else invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString + let p = OptimizedClosures.FSharpFunc<_,_,_>.Adapt p + (source1 |> toComposer' "source1", source2 |> toComposer' "source2") + ||> Composer.exists2 (fun a b -> p.Invoke(a,b)) - [] - let tryHead (source : seq<_>) = - checkNonNull "source" source - use e = source.GetEnumerator() - if (e.MoveNext()) then Some e.Current - else None + [] + let head (source : seq<_>) = + source |> toComposer |> Composer.head - [] + [] let tail (source: seq<'T>) = - checkNonNull "source" source - seq { use e = source.GetEnumerator() - if not (e.MoveNext()) then - invalidArg "source" (SR.GetString(SR.notEnoughElements)) - while e.MoveNext() do - yield e.Current } + source |> toComposer |> Composer.tail |> Upcast.enumerable + + [] + let tryLast (source : seq<_>) = + source |> toComposer |> Composer.tryLast [] let last (source : seq<_>) = - checkNonNull "source" source - use e = source.GetEnumerator() - if e.MoveNext() then - let mutable res = e.Current - while (e.MoveNext()) do res <- e.Current - res - else - invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString - - [] - let tryLast (source : seq<_>) = - checkNonNull "source" source - use e = source.GetEnumerator() - if e.MoveNext() then - let mutable res = e.Current - while (e.MoveNext()) do res <- e.Current - Some res - else - None - - [] + source |> toComposer |> Composer.last + + [] let exactlyOne (source : seq<_>) = - checkNonNull "source" source - use e = source.GetEnumerator() - if e.MoveNext() then - let v = e.Current - if e.MoveNext() then - invalidArg "source" (SR.GetString(SR.inputSequenceTooLong)) - else - v - else - invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString + source |> toComposer |> Composer.exactlyOne [] let rev source = - checkNonNull "source" source - mkDelayedSeq (fun () -> - let array = source |> toArray - Array.Reverse array - array :> seq<_>) + source |> toComposer |> Composer.rev |> Upcast.enumerable [] - let permute f (source : seq<_>) = - checkNonNull "source" source - mkDelayedSeq (fun () -> - source |> toArray |> Array.permute f :> seq<_>) + let permute f (source:seq<_>) = + source |> toComposer |> Composer.permute f |> Upcast.enumerable [] let mapFold<'T,'State,'Result> (f: 'State -> 'T -> 'Result * 'State) acc source = @@ -1829,20 +621,10 @@ namespace Microsoft.FSharp.Collections let arr,state = Array.mapFoldBack f array acc readonly arr, state - [] + [] let except (itemsToExclude: seq<'T>) (source: seq<'T>) = - checkNonNull "itemsToExclude" itemsToExclude - checkNonNull "source" source - - seq { - use e = source.GetEnumerator() - if e.MoveNext() then - let cached = HashSet(itemsToExclude, HashIdentity.Structural) - let next = e.Current - if (cached.Add next) then yield next - while e.MoveNext() do - let next = e.Current - if (cached.Add next) then yield next } + if isEmpty itemsToExclude then source else + source |> toComposer |> Composer.except itemsToExclude |> Upcast.enumerable [] let chunkBySize chunkSize (source : seq<_>) = diff --git a/src/fsharp/FSharp.Core/seq.fsi b/src/fsharp/FSharp.Core/seq.fsi index f05e9db76dd..76ca68bb866 100644 --- a/src/fsharp/FSharp.Core/seq.fsi +++ b/src/fsharp/FSharp.Core/seq.fsi @@ -7,13 +7,12 @@ namespace Microsoft.FSharp.Collections open System.Collections.Generic open Microsoft.FSharp.Core open Microsoft.FSharp.Collections - + /// Basic operations on IEnumerables. [] [] - module Seq = - + module Seq = /// Returns a new sequence that contains the cartesian product of the two input sequences. /// The first sequence. /// The second sequence. @@ -25,7 +24,7 @@ namespace Microsoft.FSharp.Collections /// Wraps the two given enumerations as a single concatenated /// enumeration. /// - /// The returned sequence may be passed between threads safely. However, + /// The returned sequence may be passed between threads safely. However, /// individual IEnumerator values generated from the returned sequence should not be accessed /// concurrently. /// @@ -37,11 +36,11 @@ namespace Microsoft.FSharp.Collections /// Thrown when either of the two provided sequences is /// null. [] - val append: source1:seq<'T> -> source2:seq<'T> -> seq<'T> + val append: source1:seq<'T> -> source2:seq<'T> -> seq<'T> /// Returns the average of the elements in the sequence. /// - /// The elements are averaged using the + operator, DivideByInt method and Zero property + /// The elements are averaged using the + operator, DivideByInt method and Zero property /// associated with the element type. /// /// The input sequence. @@ -51,15 +50,15 @@ namespace Microsoft.FSharp.Collections /// Thrown when the input sequence is null. /// Thrown when the input sequence has zero elements. [] - val inline average : source:seq<(^T)> -> ^T - when ^T : (static member ( + ) : ^T * ^T -> ^T) - and ^T : (static member DivideByInt : ^T * int -> ^T) + val inline average : source:seq<(^T)> -> ^T + when ^T : (static member ( + ) : ^T * ^T -> ^T) + and ^T : (static member DivideByInt : ^T * int -> ^T) and ^T : (static member Zero : ^T) - /// Returns the average of the results generated by applying the function to each element + /// Returns the average of the results generated by applying the function to each element /// of the sequence. /// - /// The elements are averaged using the + operator, DivideByInt method and Zero property + /// The elements are averaged using the + operator, DivideByInt method and Zero property /// associated with the generated type. /// /// A function applied to transform each element of the sequence. @@ -70,29 +69,29 @@ namespace Microsoft.FSharp.Collections /// Thrown when the input sequence is null. /// Thrown when the input sequence has zero elements. [] - val inline averageBy : projection:('T -> ^U) -> source:seq<'T> -> ^U - when ^U : (static member ( + ) : ^U * ^U -> ^U) - and ^U : (static member DivideByInt : ^U * int -> ^U) + val inline averageBy : projection:('T -> ^U) -> source:seq<'T> -> ^U + when ^U : (static member ( + ) : ^U * ^U -> ^U) + and ^U : (static member DivideByInt : ^U * int -> ^U) and ^U : (static member Zero : ^U) /// Returns a sequence that corresponds to a cached version of the input sequence. - /// This result sequence will have the same elements as the input sequence. The result - /// can be enumerated multiple times. The input sequence will be enumerated at most + /// This result sequence will have the same elements as the input sequence. The result + /// can be enumerated multiple times. The input sequence will be enumerated at most /// once and only as far as is necessary. Caching a sequence is typically useful when repeatedly /// evaluating items in the original sequence is computationally expensive or if /// iterating the sequence causes side-effects that the user does not want to be /// repeated multiple times. /// /// Enumeration of the result sequence is thread safe in the sense that multiple independent IEnumerator - /// values may be used simultaneously from different threads (accesses to + /// values may be used simultaneously from different threads (accesses to /// the internal lookaside table are thread safe). Each individual IEnumerator /// is not typically thread safe and should not be accessed concurrently. /// /// Once enumeration of the input sequence has started, /// it's enumerator will be kept live by this object until the enumeration has completed. - /// At that point, the enumerator will be disposed. + /// At that point, the enumerator will be disposed. /// - /// The enumerator may be disposed and underlying cache storage released by + /// The enumerator may be disposed and underlying cache storage released by /// converting the returned sequence object to type IDisposable, and calling the Dispose method /// on this object. The sequence object may then be re-enumerated and a fresh enumerator will /// be used. @@ -111,7 +110,7 @@ namespace Microsoft.FSharp.Collections /// An incorrect type annotation may result in runtime type /// errors. /// Individual IEnumerator values generated from the returned sequence should not be accessed concurrently. - /// + /// /// The input sequence. /// /// The result sequence. @@ -124,7 +123,7 @@ namespace Microsoft.FSharp.Collections /// the list comprised of the results "x" for each element where /// the function returns Some(x). /// - /// The returned sequence may be passed between threads safely. However, + /// The returned sequence may be passed between threads safely. However, /// individual IEnumerator values generated from the returned sequence should not /// be accessed concurrently. /// @@ -132,7 +131,7 @@ namespace Microsoft.FSharp.Collections /// The input sequence of type T. /// /// The result sequence. - /// + /// /// Thrown when the input sequence is null. [] val choose: chooser:('T -> 'U option) -> source:seq<'T> -> seq<'U> @@ -180,7 +179,7 @@ namespace Microsoft.FSharp.Collections /// Combines the given enumeration-of-enumerations as a single concatenated /// enumeration. /// - /// The returned sequence may be passed between threads safely. However, + /// The returned sequence may be passed between threads safely. However, /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. /// /// The input enumeration-of-enumerations. @@ -201,10 +200,10 @@ namespace Microsoft.FSharp.Collections /// Applies a key-generating function to each element of a sequence and returns a sequence yielding unique /// keys and their number of occurrences in the original sequence. - /// - /// Note that this function returns a sequence that digests the whole initial sequence as soon as - /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. The function makes no assumption on the ordering of the original + /// + /// Note that this function returns a sequence that digests the whole initial sequence as soon as + /// that sequence is iterated. As a result this function should not be used with + /// large or infinite sequences. The function makes no assumption on the ordering of the original /// sequence. /// /// A function transforming each item of the input sequence into a key to be @@ -220,7 +219,7 @@ namespace Microsoft.FSharp.Collections /// Returns a sequence that is built from the given delayed specification of a /// sequence. /// - /// The input function is evaluated each time an IEnumerator for the sequence + /// The input function is evaluated each time an IEnumerator for the sequence /// is requested. /// /// The generating function for the sequence. @@ -239,7 +238,7 @@ namespace Microsoft.FSharp.Collections [] val distinct: source:seq<'T> -> seq<'T> when 'T : equality - /// Returns a sequence that contains no duplicate entries according to the + /// Returns a sequence that contains no duplicate entries according to the /// generic hash and equality comparisons on the keys returned by the given key-generating function. /// If an element occurs multiple times in the sequence then the later occurrences are discarded. /// @@ -291,8 +290,8 @@ namespace Microsoft.FSharp.Collections /// Tests if any element of the sequence satisfies the given predicate. /// - /// The predicate is applied to the elements of the input sequence. If any application - /// returns true then the overall result is true and no further elements are tested. + /// The predicate is applied to the elements of the input sequence. If any application + /// returns true then the overall result is true and no further elements are tested. /// Otherwise, false is returned. /// /// A function to test each item of the input sequence. @@ -306,9 +305,9 @@ namespace Microsoft.FSharp.Collections /// Tests if any pair of corresponding elements of the input sequences satisfies the given predicate. /// - /// The predicate is applied to matching elements in the two sequences up to the lesser of the - /// two lengths of the collections. If any application returns true then the overall result is - /// true and no further elements are tested. Otherwise, false is returned. If one sequence is shorter than + /// The predicate is applied to matching elements in the two sequences up to the lesser of the + /// two lengths of the collections. If any application returns true then the overall result is + /// true and no further elements are tested. Otherwise, false is returned. If one sequence is shorter than /// the other then the remaining elements of the longer sequence are ignored. /// /// A function to test each pair of items from the input sequences. @@ -324,7 +323,7 @@ namespace Microsoft.FSharp.Collections /// Returns a new collection containing only the elements of the collection /// for which the given predicate returns "true". This is a synonym for Seq.where. /// - /// The returned sequence may be passed between threads safely. However, + /// The returned sequence may be passed between threads safely. However, /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. /// /// Remember sequence is lazy, effects are delayed until it is enumerated. @@ -334,18 +333,18 @@ namespace Microsoft.FSharp.Collections /// /// The result sequence. /// - /// Thrown when the input sequence is null. + /// Thrown when the input sequence is null. [] val filter: predicate:('T -> bool) -> source:seq<'T> -> seq<'T> /// Returns a new collection containing only the elements of the collection /// for which the given predicate returns "true". /// - /// The returned sequence may be passed between threads safely. However, + /// The returned sequence may be passed between threads safely. However, /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. /// /// Remember sequence is lazy, effects are delayed until it is enumerated. - /// + /// /// A synonym for Seq.filter. /// /// A function to test whether each item in the input sequence should be included in the output. @@ -353,7 +352,7 @@ namespace Microsoft.FSharp.Collections /// /// The result sequence. /// - /// Thrown when the input sequence is null. + /// Thrown when the input sequence is null. [] val where: predicate:('T -> bool) -> source:seq<'T> -> seq<'T> @@ -410,7 +409,7 @@ namespace Microsoft.FSharp.Collections val findIndexBack: predicate:('T -> bool) -> source:seq<'T> -> int /// Applies a function to each element of the collection, threading an accumulator argument - /// through the computation. If the input function is f and the elements are i0...iN + /// through the computation. If the input function is f and the elements are i0...iN /// then computes f (... (f s i0)...) iN /// /// A function that updates the state with each element from the sequence. @@ -464,8 +463,8 @@ namespace Microsoft.FSharp.Collections /// Tests if all elements of the sequence satisfy the given predicate. /// - /// The predicate is applied to the elements of the input sequence. If any application - /// returns false then the overall result is false and no further elements are tested. + /// The predicate is applied to the elements of the input sequence. If any application + /// returns false then the overall result is false and no further elements are tested. /// Otherwise, true is returned. /// /// A function to test an element of the input sequence. @@ -478,7 +477,7 @@ namespace Microsoft.FSharp.Collections val forall: predicate:('T -> bool) -> source:seq<'T> -> bool /// Tests the all pairs of elements drawn from the two sequences satisfy the - /// given predicate. If one sequence is shorter than + /// given predicate. If one sequence is shorter than /// the other then the remaining elements of the longer sequence are ignored. /// /// A function to test pairs of elements from the input sequences. @@ -491,13 +490,13 @@ namespace Microsoft.FSharp.Collections [] val forall2: predicate:('T1 -> 'T2 -> bool) -> source1:seq<'T1> -> source2:seq<'T2> -> bool - /// Applies a key-generating function to each element of a sequence and yields a sequence of - /// unique keys. Each unique key contains a sequence of all elements that match + /// Applies a key-generating function to each element of a sequence and yields a sequence of + /// unique keys. Each unique key contains a sequence of all elements that match /// to this key. - /// - /// This function returns a sequence that digests the whole initial sequence as soon as - /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. The function makes no assumption on the ordering of the original + /// + /// This function returns a sequence that digests the whole initial sequence as soon as + /// that sequence is iterated. As a result this function should not be used with + /// large or infinite sequences. The function makes no assumption on the ordering of the original /// sequence. /// /// A function that transforms an element of the sequence into a comparable key. @@ -581,7 +580,7 @@ namespace Microsoft.FSharp.Collections /// initialization. The function is passed the index of the item being /// generated. /// - /// The returned sequence may be passed between threads safely. However, + /// The returned sequence may be passed between threads safely. However, /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. /// /// The maximum number of items to generate for the sequence. @@ -592,14 +591,14 @@ namespace Microsoft.FSharp.Collections /// Thrown when count is negative. [] val init: count:int -> initializer:(int -> 'T) -> seq<'T> - + /// Generates a new sequence which, when iterated, will return successive /// elements by calling the given function. The results of calling the function /// will not be saved, that is the function will be reapplied as necessary to /// regenerate the elements. The function is passed the index of the item being /// generated. /// - /// The returned sequence may be passed between threads safely. However, + /// The returned sequence may be passed between threads safely. However, /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. /// Iteration can continue up to Int32.MaxValue. /// @@ -637,7 +636,7 @@ namespace Microsoft.FSharp.Collections [] val iteri: action:(int -> 'T -> unit) -> source:seq<'T> -> unit - /// Applies the given function to two collections simultaneously. If one sequence is shorter than + /// Applies the given function to two collections simultaneously. If one sequence is shorter than /// the other then the remaining elements of the longer sequence are ignored. /// /// A function to apply to each pair of elements from the input sequences. @@ -648,7 +647,7 @@ namespace Microsoft.FSharp.Collections [] val iter2: action:('T1 -> 'T2 -> unit) -> source1:seq<'T1> -> source2:seq<'T2> -> unit - /// Applies the given function to two collections simultaneously. If one sequence is shorter than + /// Applies the given function to two collections simultaneously. If one sequence is shorter than /// the other then the remaining elements of the longer sequence are ignored. The integer passed to the /// function indicates the index of element. /// @@ -675,7 +674,7 @@ namespace Microsoft.FSharp.Collections /// as elements are demanded using the MoveNext method on enumerators retrieved from the /// object. /// - /// The returned sequence may be passed between threads safely. However, + /// The returned sequence may be passed between threads safely. However, /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. /// /// A function to transform items from the input sequence. @@ -688,7 +687,7 @@ namespace Microsoft.FSharp.Collections val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U> /// Builds a new collection whose elements are the results of applying the given function - /// to the corresponding pairs of elements from the two sequences. If one input sequence is shorter than + /// to the corresponding pairs of elements from the two sequences. If one input sequence is shorter than /// the other then the remaining elements of the longer sequence are ignored. /// /// A function to transform pairs of items from the input sequences. @@ -756,7 +755,7 @@ namespace Microsoft.FSharp.Collections val mapi: mapping:(int -> 'T -> 'U) -> source:seq<'T> -> seq<'U> /// Builds a new collection whose elements are the results of applying the given function - /// to the corresponding pairs of elements from the two sequences. If one input sequence is shorter than + /// to the corresponding pairs of elements from the two sequences. If one input sequence is shorter than /// the other then the remaining elements of the longer sequence are ignored. The integer index passed to the /// function indicates the index (from 0) of element being transformed. /// @@ -779,7 +778,7 @@ namespace Microsoft.FSharp.Collections /// /// The largest element of the sequence. [] - val inline max : source:seq<'T> -> 'T when 'T : comparison + val inline max : source:seq<'T> -> 'T when 'T : comparison /// Returns the greatest of all elements of the sequence, compared via Operators.max on the function result. /// @@ -791,7 +790,7 @@ namespace Microsoft.FSharp.Collections /// Thrown when the input sequence is null. /// Thrown when the input sequence is empty. [] - val inline maxBy : projection:('T -> 'U) -> source:seq<'T> -> 'T when 'U : comparison + val inline maxBy : projection:('T -> 'U) -> source:seq<'T> -> 'T when 'U : comparison (* /// Returns the greatest function result from the elements of the sequence, compared via Operators.max. @@ -804,7 +803,7 @@ namespace Microsoft.FSharp.Collections /// Thrown when the input sequence is null. /// Thrown when the input sequence is empty. [] - val inline maxValBy : projection:('T -> 'U) -> source:seq<'T> -> 'U when 'U : comparison + val inline maxValBy : projection:('T -> 'U) -> source:seq<'T> -> 'U when 'U : comparison *) /// Returns the lowest of all elements of the sequence, compared via Operators.min. @@ -816,7 +815,7 @@ namespace Microsoft.FSharp.Collections /// Thrown when the input sequence is null. /// Thrown when the input sequence is empty. [] - val inline min : source:seq<'T> -> 'T when 'T : comparison + val inline min : source:seq<'T> -> 'T when 'T : comparison /// Returns the lowest of all elements of the sequence, compared via Operators.min on the function result. /// @@ -828,7 +827,7 @@ namespace Microsoft.FSharp.Collections /// Thrown when the input sequence is null. /// Thrown when the input sequence is empty. [] - val inline minBy : projection:('T -> 'U) -> source:seq<'T> -> 'T when 'U : comparison + val inline minBy : projection:('T -> 'U) -> source:seq<'T> -> 'T when 'U : comparison (* /// Returns the lowest function result from the elements of the sequence, compared via Operators.max. @@ -841,7 +840,7 @@ namespace Microsoft.FSharp.Collections /// Thrown when the input sequence is null. /// Thrown when the input sequence is empty. [] - val inline minValBy : projection:('T -> 'U) -> source:seq<'T> -> 'U when 'U : comparison + val inline minValBy : projection:('T -> 'U) -> source:seq<'T> -> 'U when 'U : comparison *) /// Computes the nth element in the collection. @@ -917,10 +916,10 @@ namespace Microsoft.FSharp.Collections /// Thrown when every item of the sequence /// evaluates to None when the given function is applied. [] - val pick: chooser:('T -> 'U option) -> source:seq<'T> -> 'U + val pick: chooser:('T -> 'U option) -> source:seq<'T> -> 'U - /// Builds a new sequence object that delegates to the given sequence object. This ensures - /// the original sequence cannot be rediscovered and mutated by a type cast. For example, + /// Builds a new sequence object that delegates to the given sequence object. This ensures + /// the original sequence cannot be rediscovered and mutated by a type cast. For example, /// if given an array the returned sequence will return the elements of the array, but /// you cannot cast the returned sequence object to an array. /// @@ -934,7 +933,7 @@ namespace Microsoft.FSharp.Collections /// Applies a function to each element of the sequence, threading an accumulator argument /// through the computation. Begin by applying the function to the first two elements. - /// Then feed this result into the function along with the third element and so on. + /// Then feed this result into the function along with the third element and so on. /// Return the final result. /// /// A function that takes in the current accumulated result and the next @@ -956,7 +955,7 @@ namespace Microsoft.FSharp.Collections val replicate: count:int -> initial:'T -> seq<'T> /// Applies a function to each element of the sequence, starting from the end, threading an accumulator argument - /// through the computation. If the input function is f and the elements are i0...iN + /// through the computation. If the input function is f and the elements are i0...iN /// then computes f i0 (...(f iN-1 iN)). /// A function that takes in the next-to-last element of the sequence and the /// current accumulated result to produce the next accumulated result. @@ -1023,7 +1022,7 @@ namespace Microsoft.FSharp.Collections [] val skip: count:int -> source:seq<'T> -> seq<'T> - /// Returns a sequence that, when iterated, skips elements of the underlying sequence while the + /// Returns a sequence that, when iterated, skips elements of the underlying sequence while the /// given predicate returns True, and then yields the remaining elements of the sequence. /// /// A function that evaluates an element of the sequence to a boolean value. @@ -1036,10 +1035,10 @@ namespace Microsoft.FSharp.Collections val skipWhile: predicate:('T -> bool) -> source:seq<'T> -> seq<'T> /// Yields a sequence ordered by keys. - /// - /// This function returns a sequence that digests the whole initial sequence as soon as - /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. The function makes no assumption on the ordering of the original + /// + /// This function returns a sequence that digests the whole initial sequence as soon as + /// that sequence is iterated. As a result this function should not be used with + /// large or infinite sequences. The function makes no assumption on the ordering of the original /// sequence. /// /// This is a stable sort, that is the original order of equal elements is preserved. @@ -1068,11 +1067,11 @@ namespace Microsoft.FSharp.Collections val sortWith : comparer:('T -> 'T -> int) -> source:seq<'T> -> seq<'T> /// Applies a key-generating function to each element of a sequence and yield a sequence ordered - /// by keys. The keys are compared using generic comparison as implemented by Operators.compare. - /// - /// This function returns a sequence that digests the whole initial sequence as soon as - /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. The function makes no assumption on the ordering of the original + /// by keys. The keys are compared using generic comparison as implemented by Operators.compare. + /// + /// This function returns a sequence that digests the whole initial sequence as soon as + /// that sequence is iterated. As a result this function should not be used with + /// large or infinite sequences. The function makes no assumption on the ordering of the original /// sequence. /// /// This is a stable sort, that is the original order of equal elements is preserved. @@ -1084,13 +1083,13 @@ namespace Microsoft.FSharp.Collections /// /// Thrown when the input sequence is null. [] - val sortBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> when 'Key : comparison + val sortBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> when 'Key : comparison /// Yields a sequence ordered descending by keys. - /// - /// This function returns a sequence that digests the whole initial sequence as soon as - /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. The function makes no assumption on the ordering of the original + /// + /// This function returns a sequence that digests the whole initial sequence as soon as + /// that sequence is iterated. As a result this function should not be used with + /// large or infinite sequences. The function makes no assumption on the ordering of the original /// sequence. /// /// This is a stable sort, that is the original order of equal elements is preserved. @@ -1104,11 +1103,11 @@ namespace Microsoft.FSharp.Collections val inline sortDescending : source:seq<'T> -> seq<'T> when 'T : comparison /// Applies a key-generating function to each element of a sequence and yield a sequence ordered - /// descending by keys. The keys are compared using generic comparison as implemented by Operators.compare. - /// - /// This function returns a sequence that digests the whole initial sequence as soon as - /// that sequence is iterated. As a result this function should not be used with - /// large or infinite sequences. The function makes no assumption on the ordering of the original + /// descending by keys. The keys are compared using generic comparison as implemented by Operators.compare. + /// + /// This function returns a sequence that digests the whole initial sequence as soon as + /// that sequence is iterated. As a result this function should not be used with + /// large or infinite sequences. The function makes no assumption on the ordering of the original /// sequence. /// /// This is a stable sort, that is the original order of equal elements is preserved. @@ -1130,8 +1129,8 @@ namespace Microsoft.FSharp.Collections /// /// The computed sum. [] - val inline sum : source:seq<(^T)> -> ^T - when ^T : (static member ( + ) : ^T * ^T -> ^T) + val inline sum : source:seq<(^T)> -> ^T + when ^T : (static member ( + ) : ^T * ^T -> ^T) and ^T : (static member Zero : ^T) /// Returns the sum of the results generated by applying the function to each element of the sequence. @@ -1142,8 +1141,8 @@ namespace Microsoft.FSharp.Collections /// /// The computed sum. [] - val inline sumBy : projection:('T -> ^U) -> source:seq<'T> -> ^U - when ^U : (static member ( + ) : ^U * ^U -> ^U) + val inline sumBy : projection:('T -> ^U) -> source:seq<'T> -> ^U + when ^U : (static member ( + ) : ^U * ^U -> ^U) and ^U : (static member Zero : ^U) /// Returns a sequence that skips 1 element of the underlying sequence and then yields the @@ -1175,7 +1174,7 @@ namespace Microsoft.FSharp.Collections [] val take: count:int -> source:seq<'T> -> seq<'T> - /// Returns a sequence that, when iterated, yields elements of the underlying sequence while the + /// Returns a sequence that, when iterated, yields elements of the underlying sequence while the /// given predicate returns True, and then returns no further elements. /// /// A function that evaluates to false when no more items should be returned. @@ -1197,6 +1196,16 @@ namespace Microsoft.FSharp.Collections [] val toArray: source:seq<'T> -> 'T[] + /// Builds an SeqEnumerable from the given collection. + /// + /// The input sequence. + /// + /// The result SeqEnumerable. + /// + /// Thrown when the input sequence is null. + [] + val toComposer : source:seq<'T> -> Composer.Core.ISeq<'T> + /// Builds a list from the given collection. /// /// The input sequence. @@ -1231,7 +1240,7 @@ namespace Microsoft.FSharp.Collections [] val tryFindBack: predicate:('T -> bool) -> source:seq<'T> -> 'T option - /// Returns the index of the first element in the sequence + /// Returns the index of the first element in the sequence /// that satisfies the given predicate. Return None if no such element exists. /// /// A function that evaluates to a Boolean when given an item in the sequence. @@ -1295,7 +1304,7 @@ namespace Microsoft.FSharp.Collections /// /// The stream will be recomputed each time an IEnumerator is requested and iterated for the Seq. /// - /// The returned sequence may be passed between threads safely. However, + /// The returned sequence may be passed between threads safely. However, /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently. /// /// A function that takes in the current state and returns an option tuple of the next @@ -1341,98 +1350,4 @@ namespace Microsoft.FSharp.Collections /// /// Thrown when any of the input sequences is null. [] - val zip3: source1:seq<'T1> -> source2:seq<'T2> -> source3:seq<'T3> -> seq<'T1 * 'T2 * 'T3> - -namespace Microsoft.FSharp.Core.CompilerServices - - open System - open System.Collections - open System.Collections.Generic - open Microsoft.FSharp.Core - open Microsoft.FSharp.Collections - - - [] - /// A group of functions used as part of the compiled representation of F# sequence expressions. - module RuntimeHelpers = - - [] - type internal StructBox<'T when 'T : equality> = - new : value:'T -> StructBox<'T> - member Value : 'T - static member Comparer : IEqualityComparer> - - /// The F# compiler emits calls to this function to - /// implement the while operator for F# sequence expressions. - /// - /// A function that indicates whether iteration should continue. - /// The input sequence. - /// - /// The result sequence. - val EnumerateWhile : guard:(unit -> bool) -> source:seq<'T> -> seq<'T> - - /// The F# compiler emits calls to this function to - /// implement the try/finally operator for F# sequence expressions. - /// - /// The input sequence. - /// A computation to be included in an enumerator's Dispose method. - /// - /// The result sequence. - val EnumerateThenFinally : source:seq<'T> -> compensation:(unit -> unit) -> seq<'T> - - /// The F# compiler emits calls to this function to implement the compiler-intrinsic - /// conversions from untyped System.Collections.IEnumerable sequences to typed sequences. - /// - /// An initializer function. - /// A function to iterate and test if end of sequence is reached. - /// A function to retrieve the current element. - /// - /// The resulting typed sequence. - val EnumerateFromFunctions: create:(unit -> 'T) -> moveNext:('T -> bool) -> current:('T -> 'U) -> seq<'U> - - /// The F# compiler emits calls to this function to implement the use operator for F# sequence - /// expressions. - /// - /// The resource to be used and disposed. - /// The input sequence. - /// - /// The result sequence. - val EnumerateUsing : resource:'T -> source:('T -> 'Collection) -> seq<'U> when 'T :> IDisposable and 'Collection :> seq<'U> - - /// Creates an anonymous event with the given handlers. - /// - /// A function to handle adding a delegate for the event to trigger. - /// A function to handle removing a delegate that the event triggers. - /// A function to produce the delegate type the event can trigger. - /// - /// The initialized event. - val CreateEvent : addHandler : ('Delegate -> unit) -> removeHandler : ('Delegate -> unit) -> createHandler : ((obj -> 'Args -> unit) -> 'Delegate) -> Microsoft.FSharp.Control.IEvent<'Delegate,'Args> - - [] - /// The F# compiler emits implementations of this type for compiled sequence expressions. - type GeneratedSequenceBase<'T> = - /// The F# compiler emits implementations of this type for compiled sequence expressions. - /// - /// A new sequence generator for the expression. - new : unit -> GeneratedSequenceBase<'T> - /// The F# compiler emits implementations of this type for compiled sequence expressions. - /// - /// A new enumerator for the sequence. - abstract GetFreshEnumerator : unit -> IEnumerator<'T> - /// The F# compiler emits implementations of this type for compiled sequence expressions. - /// - /// A reference to the sequence. - /// - /// A 0, 1, and 2 respectively indicate Stop, Yield, and Goto conditions for the sequence generator. - abstract GenerateNext : result:byref> -> int - /// The F# compiler emits implementations of this type for compiled sequence expressions. - abstract Close: unit -> unit - /// The F# compiler emits implementations of this type for compiled sequence expressions. - abstract CheckClose: bool - /// The F# compiler emits implementations of this type for compiled sequence expressions. - abstract LastGenerated : 'T - interface IEnumerable<'T> - interface IEnumerable - interface IEnumerator<'T> - interface IEnumerator - + val zip3: source1:seq<'T1> -> source2:seq<'T2> -> source3:seq<'T3> -> seq<'T1 * 'T2 * 'T3> \ No newline at end of file diff --git a/src/fsharp/FSharp.Core/seqcomposer.fs b/src/fsharp/FSharp.Core/seqcomposer.fs new file mode 100644 index 00000000000..0026fa3a2b8 --- /dev/null +++ b/src/fsharp/FSharp.Core/seqcomposer.fs @@ -0,0 +1,1688 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.FSharp.Collections + + open System + open System.Diagnostics + open System.Collections + open System.Collections.Generic + open System.Reflection + open Microsoft.FSharp.Core + open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators + open Microsoft.FSharp.Core.Operators + open Microsoft.FSharp.Core.CompilerServices + open Microsoft.FSharp.Control + open Microsoft.FSharp.Collections + open Microsoft.FSharp.Primitives.Basics + + [] + module Composer = + open IEnumerator + + module Core = + [] + type NoValue = struct end + + [] + type Value<'a> = + val mutable _1 : 'a + new (a:'a) = { _1 = a } + + [] + type Values<'a,'b> = + val mutable _1 : 'a + val mutable _2 : 'b + new (a:'a, b: 'b) = { _1 = a; _2 = b } + + [] + type Values<'a,'b,'c> = + val mutable _1 : 'a + val mutable _2 : 'b + val mutable _3 : 'c + new (a:'a, b:'b, c:'c) = { _1 = a; _2 = b; _3 = c } + + type PipeIdx = int + + type IOutOfBand = + abstract StopFurtherProcessing : PipeIdx -> unit + + [] + type Activity() = + abstract ChainComplete : stopTailCall:byref * PipeIdx -> unit + abstract ChainDispose : stopTailCall:byref -> unit + + [] + type Activity<'T,'U> () = + inherit Activity() + abstract ProcessNext : input:'T -> bool + + [] + type Transform<'T,'U,'State> = + inherit Activity<'T,'U> + + new (next:Activity, initState:'State) = { + inherit Activity<'T,'U> () + State = initState + Next = next + } + + val mutable State : 'State + val Next : Activity + + override this.ChainComplete (stopTailCall, terminatingIdx) = + this.Next.ChainComplete (&stopTailCall, terminatingIdx) + override this.ChainDispose stopTailCall = + this.Next.ChainDispose (&stopTailCall) + + [] + type TransformWithPostProcessing<'T,'U,'State>(next:Activity, initState:'State) = + inherit Transform<'T,'U,'State>(next, initState) + + abstract OnComplete : PipeIdx -> unit + abstract OnDispose : unit -> unit + + override this.ChainComplete (stopTailCall, terminatingIdx) = + this.OnComplete terminatingIdx + this.Next.ChainComplete (&stopTailCall, terminatingIdx) + override this.ChainDispose stopTailCall = + try this.OnDispose () + finally this.Next.ChainDispose (&stopTailCall) + + [] + type Folder<'T,'Result,'State> = + inherit Activity<'T,'T> + + val mutable Result : 'Result + val mutable State : 'State + + val mutable HaltedIdx : int + member this.StopFurtherProcessing pipeIdx = this.HaltedIdx <- pipeIdx + interface IOutOfBand with + member this.StopFurtherProcessing pipeIdx = this.StopFurtherProcessing pipeIdx + + new (initalResult,initState) = { + inherit Activity<'T,'T>() + State = initState + HaltedIdx = 0 + Result = initalResult + } + + override this.ChainComplete (_,_) = () + override this.ChainDispose _ = () + + [] + type FolderWithPostProcessing<'T,'Result,'State>(initResult,initState) = + inherit Folder<'T,'Result,'State>(initResult,initState) + + abstract OnComplete : PipeIdx -> unit + abstract OnDispose : unit -> unit + + override this.ChainComplete (stopTailCall, terminatingIdx) = + this.OnComplete terminatingIdx + override this.ChainDispose _ = + this.OnDispose () + + [] + type TransformFactory<'T,'U> () = + abstract Compose<'V> : IOutOfBand -> PipeIdx -> Activity<'U,'V> -> Activity<'T,'V> + + type ISeq<'T> = + inherit IEnumerable<'T> + abstract member PushTransform<'U> : TransformFactory<'T,'U> -> ISeq<'U> + abstract member Fold<'Result,'State> : f:(PipeIdx->Folder<'T,'Result,'State>) -> 'Result + + open Core + + module internal TailCall = + // used for performance reasons; these are not recursive calls, so should be safe + // ** it should be noted that potential changes to the f# compiler may render this function + // ineffictive ** + let inline avoid boolean = match boolean with true -> true | false -> false + + module internal Upcast = + // The f# compiler outputs unnecessary unbox.any calls in upcasts. If this functionality + // is fixed with the compiler then these functions can be removed. + let inline seq<'T,'seq when 'seq :> ISeq<'T> and 'seq : not struct> (t:'seq) : ISeq<'T> = (# "" t : ISeq<'T> #) + let inline enumerable<'T,'enumerable when 'enumerable :> IEnumerable<'T> and 'enumerable : not struct> (t:'enumerable) : IEnumerable<'T> = (# "" t : IEnumerable<'T> #) + let inline enumerator<'T,'enumerator when 'enumerator :> IEnumerator<'T> and 'enumerator : not struct> (t:'enumerator) : IEnumerator<'T> = (# "" t : IEnumerator<'T> #) + let inline enumeratorNonGeneric<'enumerator when 'enumerator :> IEnumerator and 'enumerator : not struct> (t:'enumerator) : IEnumerator = (# "" t : IEnumerator #) + let inline outOfBand<'outOfBand when 'outOfBand :> IOutOfBand and 'outOfBand : not struct> (t:'outOfBand) : IOutOfBand = (# "" t : IOutOfBand #) + + let createFold (factory:TransformFactory<_,_>) (folder:Folder<_,_,_>) pipeIdx = + factory.Compose (Upcast.outOfBand folder) pipeIdx folder + + let inline valueComparer<'T when 'T : equality> ()= + let c = HashIdentity.Structural<'T> + { new IEqualityComparer> with + member __.GetHashCode o = c.GetHashCode o._1 + member __.Equals (lhs,rhs) = c.Equals (lhs._1, rhs._1) } + + type ComposedFactory<'T,'U,'V> private (first:TransformFactory<'T,'U>, second:TransformFactory<'U,'V>) = + inherit TransformFactory<'T,'V>() + + override this.Compose<'W> (outOfBand:IOutOfBand) (pipeIdx:PipeIdx) (next:Activity<'V,'W>) : Activity<'T,'W> = + first.Compose outOfBand (pipeIdx-1) (second.Compose outOfBand pipeIdx next) + + static member Combine (first:TransformFactory<'T,'U>) (second:TransformFactory<'U,'V>) : TransformFactory<'T,'V> = + upcast ComposedFactory(first, second) + + and IdentityFactory<'T> private () = + inherit TransformFactory<'T,'T> () + static let singleton : TransformFactory<'T,'T> = upcast (IdentityFactory<'T>()) + override __.Compose<'V> (_outOfBand:IOutOfBand) (_pipeIdx:PipeIdx) (next:Activity<'T,'V>) : Activity<'T,'V> = next + static member Instance = singleton + + and ISkipable = + // Seq.init(Infinite)? lazily uses Current. The only Composer component that can do that is Skip + // and it can only do it at the start of a sequence + abstract CanSkip : unit -> bool + + type SeqProcessNextStates = + | InProcess = 0 + | NotStarted = 1 + | Finished = 2 + + type Result<'T>() = + inherit Folder<'T,'T,NoValue>(Unchecked.defaultof<'T>,Unchecked.defaultof) + + member val SeqState = SeqProcessNextStates.NotStarted with get, set + + override this.ProcessNext (input:'T) : bool = + this.Result <- input + true + + module Fold = + type IIterate<'T> = + abstract Iterate<'U,'Result,'State> : outOfBand:Folder<'U,'Result,'State> -> consumer:Activity<'T,'U> -> unit + + [] + type enumerable<'T> (enumerable:IEnumerable<'T>) = + interface IIterate<'T> with + member __.Iterate (outOfBand:Folder<'U,'Result,'State>) (consumer:Activity<'T,'U>) = + use enumerator = enumerable.GetEnumerator () + let rec iterate () = + if enumerator.MoveNext () then + consumer.ProcessNext enumerator.Current |> ignore + if outOfBand.HaltedIdx = 0 then + iterate () + iterate () + + [] + type Array<'T> (array:array<'T>) = + interface IIterate<'T> with + member __.Iterate (outOfBand:Folder<'U,'Result,'State>) (consumer:Activity<'T,'U>) = + let array = array + let rec iterate idx = + if idx < array.Length then + consumer.ProcessNext array.[idx] |> ignore + if outOfBand.HaltedIdx = 0 then + iterate (idx+1) + iterate 0 + + [] + type resizeArray<'T> (array:ResizeArray<'T>) = + interface IIterate<'T> with + member __.Iterate (outOfBand:Folder<'U,'Result,'State>) (consumer:Activity<'T,'U>) = + let array = array + let rec iterate idx = + if idx < array.Count then + consumer.ProcessNext array.[idx] |> ignore + if outOfBand.HaltedIdx = 0 then + iterate (idx+1) + iterate 0 + + [] + type List<'T> (alist:list<'T>) = + interface IIterate<'T> with + member __.Iterate (outOfBand:Folder<'U,'Result,'State>) (consumer:Activity<'T,'U>) = + let rec iterate lst = + match lst with + | hd :: tl -> + consumer.ProcessNext hd |> ignore + if outOfBand.HaltedIdx = 0 then + iterate tl + | _ -> () + iterate alist + + [] + type unfold<'S,'T> (generator:'S->option<'T*'S>, state:'S) = + interface IIterate<'T> with + member __.Iterate (outOfBand:Folder<'U,'Result,'State>) (consumer:Activity<'T,'U>) = + let generator = generator + let rec iterate current = + match generator current with + | Some (item, next) -> + consumer.ProcessNext item |> ignore + if outOfBand.HaltedIdx = 0 then + iterate next + | _ -> () + iterate state + + [] + type init<'T> (f:int->'T, terminatingIdx:int) = + interface IIterate<'T> with + member __.Iterate (outOfBand:Folder<'U,'Result,'State>) (consumer:Activity<'T,'U>) = + let terminatingIdx = terminatingIdx + let f = f + + let firstIdx = + match box consumer with + | :? ISkipable as skipping -> + let rec skip idx = + if idx = terminatingIdx || outOfBand.HaltedIdx <> 0 then + terminatingIdx + elif skipping.CanSkip () then + skip (idx+1) + else + idx + skip -1 + | _ -> -1 + + let rec iterate idx = + if idx < terminatingIdx then + consumer.ProcessNext (f (idx+1)) |> ignore + if outOfBand.HaltedIdx = 0 then + iterate (idx+1) + else + idx + else + idx + + let finalIdx = iterate firstIdx + if outOfBand.HaltedIdx = 0 && finalIdx = System.Int32.MaxValue then + raise <| System.InvalidOperationException (SR.GetString(SR.enumerationPastIntMaxValue)) + + let execute (createFolder:PipeIdx->Folder<'U,'Result,'State>) (transformFactory:TransformFactory<'T,'U>) pipeIdx (executeOn:#IIterate<'T>) = + let mutable stopTailCall = () + let result = createFolder (pipeIdx+1) + let consumer = createFold transformFactory result pipeIdx + try + executeOn.Iterate result consumer + consumer.ChainComplete (&stopTailCall, result.HaltedIdx) + result.Result + finally + consumer.ChainDispose (&stopTailCall) + + let executeThin (createFolder:PipeIdx->Folder<'T,'Result,'State>) (executeOn:#IIterate<'T>) = + let mutable stopTailCall = () + let result = createFolder 1 + try + executeOn.Iterate result result + result.ChainComplete (&stopTailCall, result.HaltedIdx) + result.Result + finally + result.ChainDispose (&stopTailCall) + + module Enumerable = + type Empty<'T>() = + let current () = failwith "library implementation error: Current should never be called" + interface IEnumerator<'T> with + member __.Current = current () + interface IEnumerator with + member __.Current = current () + member __.MoveNext () = false + member __.Reset (): unit = noReset () + interface IDisposable with + member __.Dispose () = () + + type EmptyEnumerators<'T>() = + static let element : IEnumerator<'T> = upcast (new Empty<'T> ()) + static member Element = element + + [] + type EnumeratorBase<'T>(result:Result<'T>, activity:Activity) = + interface IDisposable with + member __.Dispose () : unit = + let mutable stopTailCall = () + activity.ChainDispose (&stopTailCall) + + interface IEnumerator with + member this.Current : obj = box ((Upcast.enumerator this)).Current + member __.MoveNext () = failwith "library implementation error: derived class should implement (should be abstract)" + member __.Reset () : unit = noReset () + + interface IEnumerator<'T> with + member __.Current = + if result.SeqState = SeqProcessNextStates.InProcess then result.Result + else + match result.SeqState with + | SeqProcessNextStates.NotStarted -> notStarted() + | SeqProcessNextStates.Finished -> alreadyFinished() + | _ -> failwith "library implementation error: all states should have been handled" + + and [] EnumerableBase<'T> () = + let derivedClassShouldImplement () = + failwith "library implementation error: derived class should implement (should be abstract)" + + abstract member Append : (ISeq<'T>) -> ISeq<'T> + + default this.Append source = Upcast.seq (AppendEnumerable [this; source]) + + interface IEnumerable with + member this.GetEnumerator () : IEnumerator = + let genericEnumerable = Upcast.enumerable this + let genericEnumerator = genericEnumerable.GetEnumerator () + Upcast.enumeratorNonGeneric genericEnumerator + + interface IEnumerable<'T> with + member this.GetEnumerator () : IEnumerator<'T> = derivedClassShouldImplement () + + interface ISeq<'T> with + member __.PushTransform _ = derivedClassShouldImplement () + member __.Fold _ = derivedClassShouldImplement () + + and Enumerator<'T,'U>(source:IEnumerator<'T>, activity:Activity<'T,'U>, result:Result<'U>) = + inherit EnumeratorBase<'U>(result, activity) + + let rec moveNext () = + if (result.HaltedIdx = 0) && source.MoveNext () then + if activity.ProcessNext source.Current then + true + else + moveNext () + else + result.SeqState <- SeqProcessNextStates.Finished + let mutable stopTailCall = () + activity.ChainComplete (&stopTailCall, result.HaltedIdx) + false + + interface IEnumerator with + member __.MoveNext () = + result.SeqState <- SeqProcessNextStates.InProcess + moveNext () + + interface IDisposable with + member __.Dispose () = + try + source.Dispose () + finally + let mutable stopTailCall = () + activity.ChainDispose (&stopTailCall) + + and Enumerable<'T,'U>(enumerable:IEnumerable<'T>, current:TransformFactory<'T,'U>, pipeIdx:PipeIdx) = + inherit EnumerableBase<'U>() + + interface IEnumerable<'U> with + member this.GetEnumerator () : IEnumerator<'U> = + let result = Result<'U> () + Upcast.enumerator (new Enumerator<'T,'U>(enumerable.GetEnumerator(), createFold current result pipeIdx, result)) + + interface ISeq<'U> with + member __.PushTransform (next:TransformFactory<'U,'V>) : ISeq<'V> = + Upcast.seq (new Enumerable<'T,'V>(enumerable, ComposedFactory.Combine current next, pipeIdx+1)) + + member this.Fold<'Result,'State> (f:PipeIdx->Folder<'U,'Result,'State>) = + Fold.execute f current pipeIdx (Fold.enumerable enumerable) + + and EnumerableThin<'T>(enumerable:IEnumerable<'T>) = + inherit EnumerableBase<'T>() + + interface IEnumerable<'T> with + member this.GetEnumerator () = enumerable.GetEnumerator () + + interface ISeq<'T> with + member __.PushTransform (next:TransformFactory<'T,'U>) : ISeq<'U> = + Upcast.seq (new Enumerable<'T,'U>(enumerable, next, 1)) + + member this.Fold<'Result,'State> (f:PipeIdx->Folder<'T,'Result,'State>) = + Fold.executeThin f (Fold.enumerable enumerable) + + and SeqDelayed<'T>(delayed:unit->ISeq<'T>, pipeIdx:PipeIdx) = + inherit EnumerableBase<'T>() + + interface IEnumerable<'T> with + member this.GetEnumerator () : IEnumerator<'T> = (delayed()).GetEnumerator () + + interface ISeq<'T> with + member __.PushTransform (next:TransformFactory<'T,'U>) : ISeq<'U> = + Upcast.seq (new SeqDelayed<'U>((fun () -> (delayed()).PushTransform next), pipeIdx+1)) + + member this.Fold<'Result,'State> (f:PipeIdx->Folder<'T,'Result,'State>) = + (delayed()).Fold f + + and ConcatEnumerator<'T, 'Collection when 'Collection :> seq<'T>> (sources:seq<'Collection>) = + let mutable state = SeqProcessNextStates.NotStarted + let main = sources.GetEnumerator () + + let mutable active = EmptyEnumerators.Element + + let rec moveNext () = + if active.MoveNext () then + true + elif main.MoveNext () then + active.Dispose () + active <- main.Current.GetEnumerator () + moveNext () + else + state <- SeqProcessNextStates.Finished + false + + interface IEnumerator<'T> with + member __.Current = + if state = SeqProcessNextStates.InProcess then active.Current + else + match state with + | SeqProcessNextStates.NotStarted -> notStarted() + | SeqProcessNextStates.Finished -> alreadyFinished() + | _ -> failwith "library implementation error: all states should have been handled" + + interface IEnumerator with + member this.Current = box ((Upcast.enumerator this)).Current + member __.MoveNext () = + state <- SeqProcessNextStates.InProcess + moveNext () + member __.Reset () = noReset () + + interface IDisposable with + member __.Dispose () = + main.Dispose () + active.Dispose () + + and AppendEnumerable<'T> (sources:list>) = + inherit EnumerableBase<'T>() + + interface IEnumerable<'T> with + member this.GetEnumerator () : IEnumerator<'T> = + Upcast.enumerator (new ConcatEnumerator<_,_> (sources |> List.rev)) + + override this.Append source = + Upcast.seq (AppendEnumerable (source::sources)) + + interface ISeq<'T> with + member this.PushTransform (next:TransformFactory<'T,'U>) : ISeq<'U> = + Upcast.seq (Enumerable<'T,'V>(this, next, 1)) + + member this.Fold<'Result,'State> (f:PipeIdx->Folder<'T,'Result,'State>) = + Fold.executeThin f (Fold.enumerable this) + + and ConcatEnumerable<'T, 'Collection when 'Collection :> seq<'T>> (sources:seq<'Collection>) = + inherit EnumerableBase<'T>() + + interface IEnumerable<'T> with + member this.GetEnumerator () : IEnumerator<'T> = + Upcast.enumerator (new ConcatEnumerator<_,_> (sources)) + + interface ISeq<'T> with + member this.PushTransform (next:TransformFactory<'T,'U>) : ISeq<'U> = + Upcast.seq (Enumerable<'T,'V>(this, next, 1)) + + member this.Fold<'Result,'State> (f:PipeIdx->Folder<'T,'Result,'State>) = + Fold.executeThin f (Fold.enumerable this) + + let create enumerable current = + Upcast.seq (Enumerable (enumerable, current, 1)) + + module EmptyEnumerable = + type Enumerable<'T> () = + inherit Enumerable.EnumerableBase<'T>() + + static let singleton = Enumerable<'T>() :> ISeq<'T> + static member Instance = singleton + + interface IEnumerable<'T> with + member this.GetEnumerator () : IEnumerator<'T> = IEnumerator.Empty<'T>() + + override this.Append source = + Upcast.seq (Enumerable.EnumerableThin<'T> source) + + interface ISeq<'T> with + member this.PushTransform (next:TransformFactory<'T,'U>) : ISeq<'U> = + Upcast.seq (Enumerable.Enumerable<'T,'V>(this, next, 1)) + + member this.Fold<'Result,'State> (f:PipeIdx->Folder<'T,'Result,'State>) = + Fold.executeThin f (Fold.enumerable this) + + module Array = + type Enumerator<'T,'U>(array:array<'T>, activity:Activity<'T,'U>, result:Result<'U>) = + inherit Enumerable.EnumeratorBase<'U>(result, activity) + + let mutable idx = 0 + + let rec moveNext () = + if (result.HaltedIdx = 0) && idx < array.Length then + idx <- idx+1 + if activity.ProcessNext array.[idx-1] then + true + else + moveNext () + else + result.SeqState <- SeqProcessNextStates.Finished + let mutable stopTailCall = () + activity.ChainComplete (&stopTailCall, result.HaltedIdx) + false + + interface IEnumerator with + member __.MoveNext () = + result.SeqState <- SeqProcessNextStates.InProcess + moveNext () + + type Enumerable<'T,'U>(array:array<'T>, transformFactory:TransformFactory<'T,'U>, pipeIdx:PipeIdx) = + inherit Enumerable.EnumerableBase<'U>() + + interface IEnumerable<'U> with + member this.GetEnumerator () : IEnumerator<'U> = + let result = Result<'U> () + Upcast.enumerator (new Enumerator<'T,'U>(array, createFold transformFactory result pipeIdx, result)) + + interface ISeq<'U> with + member __.PushTransform (next:TransformFactory<'U,'V>) : ISeq<'V> = + Upcast.seq (new Enumerable<'T,'V>(array, ComposedFactory.Combine transformFactory next, 1)) + + member this.Fold<'Result,'State> (f:PipeIdx->Folder<'U,'Result,'State>) = + Fold.execute f transformFactory pipeIdx (Fold.Array array) + + module ResizeArray = + type Enumerator<'T,'U>(array:ResizeArray<'T>, activity:Activity<'T,'U>, result:Result<'U>) = + inherit Enumerable.EnumeratorBase<'U>(result, activity) + + let mutable idx = 0 + + let rec moveNext () = + if (result.HaltedIdx = 0) && idx < array.Count then + idx <- idx+1 + if activity.ProcessNext array.[idx-1] then + true + else + moveNext () + else + result.SeqState <- SeqProcessNextStates.Finished + let mutable stopTailCall = () + activity.ChainComplete (&stopTailCall, result.HaltedIdx) + false + + interface IEnumerator with + member __.MoveNext () = + result.SeqState <- SeqProcessNextStates.InProcess + moveNext () + + type Enumerable<'T,'U>(resizeArray:ResizeArray<'T>, transformFactory:TransformFactory<'T,'U>, pipeIdx:PipeIdx) = + inherit Enumerable.EnumerableBase<'U>() + + interface IEnumerable<'U> with + member this.GetEnumerator () : IEnumerator<'U> = + let result = Result<'U> () + Upcast.enumerator (new Enumerator<'T,'U>(resizeArray, createFold transformFactory result pipeIdx, result)) + + interface ISeq<'U> with + member __.PushTransform (next:TransformFactory<'U,'V>) : ISeq<'V> = + Upcast.seq (new Enumerable<'T,'V>(resizeArray, ComposedFactory.Combine transformFactory next, 1)) + + member this.Fold<'Result,'State> (f:PipeIdx->Folder<'U,'Result,'State>) = + Fold.execute f transformFactory pipeIdx (Fold.resizeArray resizeArray) + + module List = + type Enumerator<'T,'U>(alist:list<'T>, activity:Activity<'T,'U>, result:Result<'U>) = + inherit Enumerable.EnumeratorBase<'U>(result, activity) + + let mutable list = alist + + let rec moveNext current = + match result.HaltedIdx, current with + | 0, head::tail -> + if activity.ProcessNext head then + list <- tail + true + else + moveNext tail + | _ -> + result.SeqState <- SeqProcessNextStates.Finished + let mutable stopTailCall = () + activity.ChainComplete (&stopTailCall, result.HaltedIdx) + false + + interface IEnumerator with + member __.MoveNext () = + result.SeqState <- SeqProcessNextStates.InProcess + moveNext list + + type Enumerable<'T,'U>(alist:list<'T>, transformFactory:TransformFactory<'T,'U>, pipeIdx:PipeIdx) = + inherit Enumerable.EnumerableBase<'U>() + + interface IEnumerable<'U> with + member this.GetEnumerator () : IEnumerator<'U> = + let result = Result<'U> () + Upcast.enumerator (new Enumerator<'T,'U>(alist, createFold transformFactory result pipeIdx, result)) + + interface ISeq<'U> with + member __.PushTransform (next:TransformFactory<'U,'V>) : ISeq<'V> = + Upcast.seq (new Enumerable<'T,'V>(alist, ComposedFactory.Combine transformFactory next, pipeIdx+1)) + + member this.Fold<'Result,'State> (f:PipeIdx->Folder<'U,'Result,'State>) = + Fold.execute f transformFactory pipeIdx (Fold.List alist) + + let create alist current = + Upcast.seq (Enumerable(alist, current, 1)) + + module Unfold = + type Enumerator<'T,'U,'State>(generator:'State->option<'T*'State>, state:'State, activity:Activity<'T,'U>, result:Result<'U>) = + inherit Enumerable.EnumeratorBase<'U>(result, activity) + + let mutable current = state + + let rec moveNext () = + match result.HaltedIdx, generator current with + | 0, Some (item, nextState) -> + current <- nextState + if activity.ProcessNext item then + true + else + moveNext () + | _ -> false + + interface IEnumerator with + member __.MoveNext () = + result.SeqState <- SeqProcessNextStates.InProcess + moveNext () + + type Enumerable<'T,'U,'GeneratorState>(generator:'GeneratorState->option<'T*'GeneratorState>, state:'GeneratorState, transformFactory:TransformFactory<'T,'U>, pipeIdx:PipeIdx) = + inherit Enumerable.EnumerableBase<'U>() + + interface IEnumerable<'U> with + member this.GetEnumerator () : IEnumerator<'U> = + let result = Result<'U> () + Upcast.enumerator (new Enumerator<'T,'U,'GeneratorState>(generator, state, createFold transformFactory result pipeIdx, result)) + + interface ISeq<'U> with + member this.PushTransform (next:TransformFactory<'U,'V>) : ISeq<'V> = + Upcast.seq (new Enumerable<'T,'V,'GeneratorState>(generator, state, ComposedFactory.Combine transformFactory next, pipeIdx+1)) + + member this.Fold<'Result,'State> (f:PipeIdx->Folder<'U,'Result,'State>) = + Fold.execute f transformFactory pipeIdx (Fold.unfold (generator, state)) + + module Init = + // The original implementation of "init" delayed the calculation of Current, and so it was possible + // to do MoveNext without it's value being calculated. + // I can imagine only two scenerios where that is possibly sane, although a simple solution is readily + // at hand in both cases. The first is that of an expensive generator function, where you skip the + // first n elements. The simple solution would have just been to have a map ((+) n) as the first operation + // instead. The second case would be counting elements, but that is only of use if you're not filtering + // or mapping or doing anything else (as that would cause Current to be evaluated!) and + // so you already know what the count is!! Anyway, someone thought it was a good idea, so + // I have had to add an extra function that is used in Skip to determine if we are touching + // Current or not. + + let getTerminatingIdx (count:Nullable) = + // we are offset by 1 to allow for values going up to System.Int32.MaxValue + // System.Int32.MaxValue is an illegal value for the "infinite" sequence + if count.HasValue then + count.Value - 1 + else + System.Int32.MaxValue + + type Enumerator<'T,'U>(count:Nullable, f:int->'T, activity:Activity<'T,'U>, result:Result<'U>) = + inherit Enumerable.EnumeratorBase<'U>(result, activity) + + let isSkipping = + match box activity with + | :? ISkipable as skip -> skip.CanSkip + | _ -> fun () -> false + + let terminatingIdx = + getTerminatingIdx count + + let mutable maybeSkipping = true + let mutable idx = -1 + + let rec moveNext () = + if result.HaltedIdx = 0 && idx < terminatingIdx then + idx <- idx + 1 + + if maybeSkipping then + // Skip can only is only checked at the start of the sequence, so once + // triggered, we stay triggered. + maybeSkipping <- isSkipping () + + if maybeSkipping then + moveNext () + elif activity.ProcessNext (f idx) then + true + else + moveNext () + elif result.HaltedIdx = 0 && idx = System.Int32.MaxValue then + raise <| System.InvalidOperationException (SR.GetString(SR.enumerationPastIntMaxValue)) + else + result.SeqState <- SeqProcessNextStates.Finished + let mutable stopTailCall = () + activity.ChainComplete (&stopTailCall, result.HaltedIdx) + false + + interface IEnumerator with + member __.MoveNext () = + result.SeqState <- SeqProcessNextStates.InProcess + moveNext () + + type Enumerable<'T,'U>(count:Nullable, f:int->'T, transformFactory:TransformFactory<'T,'U>, pipeIdx:PipeIdx) = + inherit Enumerable.EnumerableBase<'U>() + + interface IEnumerable<'U> with + member this.GetEnumerator () : IEnumerator<'U> = + let result = Result<'U> () + Upcast.enumerator (new Enumerator<'T,'U>(count, f, createFold transformFactory result pipeIdx, result)) + + interface ISeq<'U> with + member this.PushTransform (next:TransformFactory<'U,'V>) : ISeq<'V> = + Upcast.seq (new Enumerable<'T,'V>(count, f, ComposedFactory.Combine transformFactory next, pipeIdx+1)) + + member this.Fold<'Result,'State> (createResult:PipeIdx->Folder<'U,'Result,'State>) = + let terminatingIdx = getTerminatingIdx count + Fold.execute createResult transformFactory pipeIdx (Fold.init (f, terminatingIdx)) + + let upto lastOption f = + match lastOption with + | Some b when b<0 -> failwith "library implementation error: upto can never be called with a negative value" + | _ -> + let unstarted = -1 // index value means unstarted (and no valid index) + let completed = -2 // index value means completed (and no valid index) + let unreachable = -3 // index is unreachable from 0,1,2,3,... + let finalIndex = match lastOption with + | Some b -> b // here b>=0, a valid end value. + | None -> unreachable // run "forever", well as far as Int32.MaxValue since indexing with a bounded type. + // The Current value for a valid index is "f i". + // Lazy<_> values are used as caches, to store either the result or an exception if thrown. + // These "Lazy<_>" caches are created only on the first call to current and forced immediately. + // The lazy creation of the cache nodes means enumerations that skip many Current values are not delayed by GC. + // For example, the full enumeration of Seq.initInfinite in the tests. + // state + let index = ref unstarted + // a Lazy node to cache the result/exception + let current = ref (Unchecked.defaultof<_>) + let setIndex i = index := i; current := (Unchecked.defaultof<_>) // cache node unprimed, initialised on demand. + let getCurrent() = + if !index = unstarted then notStarted() + if !index = completed then alreadyFinished() + match box !current with + | null -> current := Lazy<_>.Create(fun () -> f !index) + | _ -> () + // forced or re-forced immediately. + (!current).Force() + { new IEnumerator<'U> with + member x.Current = getCurrent() + interface IEnumerator with + member x.Current = box (getCurrent()) + member x.MoveNext() = + if !index = completed then + false + elif !index = unstarted then + setIndex 0 + true + else ( + if !index = System.Int32.MaxValue then raise <| System.InvalidOperationException (SR.GetString(SR.enumerationPastIntMaxValue)) + if !index = finalIndex then + false + else + setIndex (!index + 1) + true + ) + member this.Reset() = noReset() + interface System.IDisposable with + member x.Dispose () = () } + + type EnumerableDecider<'T>(count:Nullable, f:int->'T, pipeIdx:PipeIdx) = + inherit Enumerable.EnumerableBase<'T>() + + interface IEnumerable<'T> with + member this.GetEnumerator () : IEnumerator<'T> = + // we defer back to the original implementation as, as it's quite idiomatic in it's decision + // to calculate Current in a lazy fashion. I doubt anyone is really using this functionality + // in the way presented, but it's possible. + upto (if count.HasValue then Some (count.Value-1) else None) f + + interface ISeq<'T> with + member this.PushTransform (next:TransformFactory<'T,'U>) : ISeq<'U> = + Upcast.seq (Enumerable<'T,'V>(count, f, next, pipeIdx+1)) + + member this.Fold<'Result,'State> (f:PipeIdx->Folder<'T,'Result,'State>) = + Fold.executeThin f (Fold.enumerable (Upcast.enumerable this)) + + [] + let ofResizeArrayUnchecked (source:ResizeArray<'T>) : ISeq<'T> = + Upcast.seq (ResizeArray.Enumerable (source, IdentityFactory.Instance, 1)) + + [] + let ofArray (source:array<'T>) : ISeq<'T> = + Upcast.seq (Array.Enumerable (source, IdentityFactory.Instance, 1)) + + [] + let ofList (source:list<'T>) : ISeq<'T> = + Upcast.seq (List.Enumerable (source, IdentityFactory.Instance, 1)) + + [] + let ofSeq (source:seq<'T>) : ISeq<'T> = + match source with + | :? ISeq<'T> as seq -> seq + | :? array<'T> as array -> ofArray array + | :? list<'T> as list -> ofList list + | null -> nullArg "source" + | _ -> Upcast.seq (Enumerable.EnumerableThin<'T> source) + + [] + let inline average (source:ISeq<'T>) = + source.Fold (fun _ -> + upcast { new FolderWithPostProcessing<'T,'T,int> (LanguagePrimitives.GenericZero, 0) with + override this.ProcessNext value = + this.Result <- Checked.(+) this.Result value + this.State <- this.State + 1 + Unchecked.defaultof<_> (* return value unused in Fold context *) + + override this.OnComplete _ = + if this.State = 0 then + invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString + this.Result <- LanguagePrimitives.DivideByInt<'T> this.Result this.State + override this.OnDispose () = () }) + + [] + let inline averageBy (f:'T->'U) (source:ISeq<'T>) = + source.Fold (fun _ -> + upcast { new FolderWithPostProcessing<'T,'U,int>(LanguagePrimitives.GenericZero,0) with + override this.ProcessNext value = + this.Result <- Checked.(+) this.Result (f value) + this.State <- this.State + 1 + Unchecked.defaultof<_> (* return value unused in Fold context *) + + override this.OnComplete _ = + if this.State = 0 then + invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString + this.Result <- LanguagePrimitives.DivideByInt<'U> this.Result this.State + override this.OnDispose () = () }) + + [] + let empty<'T> = EmptyEnumerable.Enumerable<'T>.Instance + + [] + let exactlyOne (source:ISeq<'T>) : 'T = + source.Fold (fun pipeIdx -> + upcast { new FolderWithPostProcessing<'T,'T,Values>(Unchecked.defaultof<'T>, Values(true, false)) with + override this.ProcessNext value = + if this.State._1 then + this.State._1 <- false + this.Result <- value + else + this.State._2 <- true + this.StopFurtherProcessing pipeIdx + Unchecked.defaultof<_> (* return value unused in Fold context *) + + override this.OnComplete _ = + if this.State._1 then + invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString + elif this.State._2 then + invalidArg "source" (SR.GetString SR.inputSequenceTooLong) + override this.OnDispose () = () }) + + [] + let inline fold<'T,'State> (f:'State->'T->'State) (seed:'State) (source:ISeq<'T>) : 'State = + source.Fold (fun _ -> + upcast { new Folder<'T,'State,NoValue>(seed,Unchecked.defaultof) with + override this.ProcessNext value = + this.Result <- f this.Result value + Unchecked.defaultof<_> (* return value unused in Fold context *) }) + + [] + let inline fold2<'T1,'T2,'State> (folder:'State->'T1->'T2->'State) (state:'State) (source1:ISeq<'T1>) (source2: ISeq<'T2>) = + source1.Fold (fun pipeIdx -> + upcast { new FolderWithPostProcessing<_,'State,IEnumerator<'T2>>(state,source2.GetEnumerator()) with + override this.ProcessNext value = + if this.State.MoveNext() then + this.Result <- folder this.Result value this.State.Current + else + this.StopFurtherProcessing pipeIdx + Unchecked.defaultof<_> (* return value unused in Fold context *) + + override this.OnComplete _ = () + override this.OnDispose () = this.State.Dispose () }) + + [] + let unfold (generator:'State->option<'T * 'State>) (state:'State) : ISeq<'T> = + Upcast.seq (new Unfold.Enumerable<'T,'T,'State>(generator, state, IdentityFactory.Instance, 1)) + + [] + let initInfinite<'T> (f:int->'T) : ISeq<'T> = + Upcast.seq (new Init.EnumerableDecider<'T>(Nullable (), f, 1)) + + [] + let init<'T> (count:int) (f:int->'T) : ISeq<'T> = + if count < 0 then invalidArgInputMustBeNonNegative "count" count + elif count = 0 then empty else + Upcast.seq (new Init.EnumerableDecider<'T>(Nullable count, f, 1)) + + [] + let inline iter f (source:ISeq<'T>) = + source.Fold (fun _ -> + upcast { new Folder<'T,unit,NoValue> ((),Unchecked.defaultof) with + override this.ProcessNext value = + f value + Unchecked.defaultof<_> (* return value unused in Fold context *) }) + + [] + let inline iter2 (f:'T->'U->unit) (source1:ISeq<'T>) (source2:ISeq<'U>) : unit = + source1.Fold (fun pipeIdx -> + upcast { new FolderWithPostProcessing<'T,unit,IEnumerator<'U>> ((),source2.GetEnumerator()) with + override this.ProcessNext value = + if this.State.MoveNext() then + f value this.State.Current + else + this.StopFurtherProcessing pipeIdx + Unchecked.defaultof<_> (* return value unused in Fold context *) + + override this.OnComplete _ = () + override this.OnDispose () = this.State.Dispose () }) + + [] + let inline iteri2 (f:int->'T->'U->unit) (source1:ISeq<'T>) (source2:ISeq<'U>) : unit = + source1.Fold (fun pipeIdx -> + upcast { new FolderWithPostProcessing<'T,unit,Values>>((),Values<_,_>(-1,source2.GetEnumerator())) with + override this.ProcessNext value = + if this.State._2.MoveNext() then + f this.State._1 value this.State._2.Current + this.State._1 <- this.State._1 + 1 + Unchecked.defaultof<_> + else + this.StopFurtherProcessing pipeIdx + Unchecked.defaultof<_> + override this.OnComplete _ = () + override this.OnDispose () = this.State._2.Dispose () }) + + [] + let tryHead (source:ISeq<'T>) = + source.Fold (fun pipeIdx -> + upcast { new Folder<'T, Option<'T>,NoValue> (None,Unchecked.defaultof) with + override this.ProcessNext value = + this.Result <- Some value + this.StopFurtherProcessing pipeIdx + Unchecked.defaultof<_> (* return value unused in Fold context *) }) + + [] + let head (source:ISeq<_>) = + match tryHead source with + | None -> invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString + | Some x -> x + + [] + let inline iteri f (source:ISeq<'T>) = + source.Fold (fun _ -> + { new Folder<'T,unit,int> ((),0) with + override this.ProcessNext value = + f this.State value + this.State <- this.State + 1 + Unchecked.defaultof<_> (* return value unused in Fold context *) }) + + [] + let inline except (itemsToExclude: seq<'T>) (source:ISeq<'T>) : ISeq<'T> when 'T:equality = + source.PushTransform { new TransformFactory<'T,'T>() with + override __.Compose _ _ next = + upcast { new Transform<'T,'V,Lazy>>(next,lazy(HashSet<'T>(itemsToExclude,HashIdentity.Structural<'T>))) with + override this.ProcessNext (input:'T) : bool = + this.State.Value.Add input && TailCall.avoid (next.ProcessNext input) }} + + [] + let inline exists f (source:ISeq<'T>) = + source.Fold (fun pipeIdx -> + upcast { new Folder<'T, bool,NoValue> (false,Unchecked.defaultof) with + override this.ProcessNext value = + if f value then + this.Result <- true + this.StopFurtherProcessing pipeIdx + Unchecked.defaultof<_> (* return value unused in Fold context *) }) + + [] + let inline exists2 (predicate:'T->'U->bool) (source1:ISeq<'T>) (source2: ISeq<'U>) : bool = + source1.Fold (fun pipeIdx -> + upcast { new FolderWithPostProcessing<'T,bool,IEnumerator<'U>>(false,source2.GetEnumerator()) with + override this.ProcessNext value = + if this.State.MoveNext() then + if predicate value this.State.Current then + this.Result <- true + this.StopFurtherProcessing pipeIdx + else + this.StopFurtherProcessing pipeIdx + Unchecked.defaultof<_> (* return value unused in Fold context *) + + override this.OnComplete _ = () + override this.OnDispose () = this.State.Dispose () }) + + [] + let inline contains element (source:ISeq<'T>) = + source.Fold (fun pipeIdx -> + upcast { new Folder<'T, bool,NoValue> (false,Unchecked.defaultof) with + override this.ProcessNext value = + if element = value then + this.Result <- true + this.StopFurtherProcessing pipeIdx + Unchecked.defaultof<_> (* return value unused in Fold context *) }) + + [] + let inline forall predicate (source:ISeq<'T>) = + source.Fold (fun pipeIdx -> + upcast { new Folder<'T, bool,NoValue> (true,Unchecked.defaultof) with + override this.ProcessNext value = + if not (predicate value) then + this.Result <- false + this.StopFurtherProcessing pipeIdx + Unchecked.defaultof<_> (* return value unused in Fold context *) }) + + [] + let inline forall2 predicate (source1:ISeq<'T>) (source2:ISeq<'U>) : bool = + source1.Fold (fun pipeIdx -> + upcast { new FolderWithPostProcessing<'T,bool,IEnumerator<'U>>(true,source2.GetEnumerator()) with + override this.ProcessNext value = + if this.State.MoveNext() then + if not (predicate value this.State.Current) then + this.Result <- false + this.StopFurtherProcessing pipeIdx + else + this.StopFurtherProcessing pipeIdx + Unchecked.defaultof<_> (* return value unused in Fold context *) + + override this.OnComplete _ = () + override this.OnDispose () = this.State.Dispose () }) + + [] + let inline filter<'T> (f:'T->bool) (source:ISeq<'T>) : ISeq<'T> = + source.PushTransform { new TransformFactory<'T,'T>() with + override __.Compose _ _ next = + upcast { new Transform<'T,'V,NoValue>(next,Unchecked.defaultof) with + override __.ProcessNext input = + if f input then TailCall.avoid (next.ProcessNext input) + else false } } + + [] + let inline map<'T,'U> (f:'T->'U) (source:ISeq<'T>) : ISeq<'U> = + source.PushTransform { new TransformFactory<'T,'U>() with + override __.Compose _ _ next = + upcast { new Transform<'T,'V,NoValue>(next,Unchecked.defaultof) with + override __.ProcessNext input = + TailCall.avoid (next.ProcessNext (f input)) } } + + [] + let inline mapi f (source:ISeq<_>) = + source.PushTransform { new TransformFactory<'T,'U>() with + override __.Compose _ _ next = + upcast { new Transform<'T,'V,int>(next, -1) with + override this.ProcessNext (input:'T) : bool = + this.State <- this.State + 1 + TailCall.avoid (next.ProcessNext (f this.State input)) } } + + [] + let inline map2<'T,'U,'V> (map:'T->'U->'V) (source1:ISeq<'T>) (source2:ISeq<'U>) : ISeq<'V> = + source1.PushTransform { new TransformFactory<'T,'V>() with + override __.Compose outOfBand pipeIdx (next:Activity<'V,'W>) = + upcast { new TransformWithPostProcessing<'T,'W, IEnumerator<'U>>(next, (source2.GetEnumerator ())) with + override this.ProcessNext input = + if this.State.MoveNext () then + TailCall.avoid (next.ProcessNext (map input this.State.Current)) + else + outOfBand.StopFurtherProcessing pipeIdx + false + override this.OnComplete _ = () + override this.OnDispose () = this.State.Dispose () }} + + [] + let inline mapi2<'T,'U,'V> (map:int->'T->'U->'V) (source1:ISeq<'T>) (source2:ISeq<'U>) : ISeq<'V> = + source1.PushTransform { new TransformFactory<'T,'V>() with + override __.Compose<'W> outOfBand pipeIdx next = + upcast { new TransformWithPostProcessing<'T,'W, Values>>(next, Values<_,_>(-1,source2.GetEnumerator ())) with + override this.ProcessNext t = + let idx : byref<_> = &this.State._1 + let u = this.State._2 + if u.MoveNext () then + idx <- idx + 1 + TailCall.avoid (next.ProcessNext (map idx t u.Current)) + else + outOfBand.StopFurtherProcessing pipeIdx + false + override this.OnDispose () = this.State._2.Dispose () + override this.OnComplete _ = () }} + + [] + let inline map3<'T,'U,'V,'W>(map:'T->'U->'V->'W) (source1:ISeq<'T>) (source2:ISeq<'U>) (source3:ISeq<'V>) : ISeq<'W> = + source1.PushTransform { new TransformFactory<'T,'W>() with + override __.Compose<'X> outOfBand pipeIdx next = + upcast { new TransformWithPostProcessing<'T,'X,Values,IEnumerator<'V>>>(next,Values<_,_>(source2.GetEnumerator(),source3.GetEnumerator())) with + override this.ProcessNext t = + let u = this.State._1 + let v = this.State._2 + if u.MoveNext() && v.MoveNext () then + TailCall.avoid (next.ProcessNext (map t u.Current v.Current)) + else + outOfBand.StopFurtherProcessing pipeIdx + false + override this.OnComplete _ = () + override this.OnDispose () = + this.State._1.Dispose () + this.State._2.Dispose () }} + + [] + let inline compareWith (f:'T->'T->int) (source1:ISeq<'T>) (source2:ISeq<'T>) : int = + source1.Fold (fun pipeIdx -> + upcast { new FolderWithPostProcessing<'T,int,IEnumerator<'T>>(0,source2.GetEnumerator()) with + override this.ProcessNext value = + if not (this.State.MoveNext()) then + this.Result <- 1 + this.StopFurtherProcessing pipeIdx + else + let c = f value this.State.Current + if c <> 0 then + this.Result <- c + this.StopFurtherProcessing pipeIdx + Unchecked.defaultof<_> (* return value unused in Fold context *) + override this.OnComplete _ = + if this.Result = 0 && this.State.MoveNext() then + this.Result <- -1 + override this.OnDispose () = this.State.Dispose () }) + + [] + let inline choose (f:'T->option<'U>) (source:ISeq<'T>) : ISeq<'U> = + source.PushTransform { new TransformFactory<'T,'U>() with + override __.Compose _ _ next = + upcast { new Transform<'T,'V,NoValue>(next,Unchecked.defaultof) with + override __.ProcessNext input = + match f input with + | Some value -> TailCall.avoid (next.ProcessNext value) + | None -> false } } + + [] + let inline distinct (source:ISeq<'T>) : ISeq<'T> when 'T:equality = + source.PushTransform { new TransformFactory<'T,'T>() with + override __.Compose _ _ next = + upcast { new Transform<'T,'V,HashSet<'T>>(next,HashSet HashIdentity.Structural) with + override this.ProcessNext (input:'T) : bool = + this.State.Add input && TailCall.avoid (next.ProcessNext input) }} + + [] + let inline distinctBy (keyf:'T->'Key) (source:ISeq<'T>) :ISeq<'T> when 'Key:equality = + source.PushTransform { new TransformFactory<'T,'T>() with + override __.Compose _ _ next = + upcast { new Transform<'T,'V,HashSet<'Key>> (next,HashSet HashIdentity.Structural) with + override this.ProcessNext (input:'T) : bool = + this.State.Add (keyf input) && TailCall.avoid (next.ProcessNext input) }} + + [] + let inline max (source:ISeq<'T>) : 'T when 'T:comparison = + source.Fold (fun _ -> + upcast { new FolderWithPostProcessing<'T,'T,bool>(Unchecked.defaultof<'T>,true) with + override this.ProcessNext value = + if this.State then + this.State <- false + this.Result <- value + elif value > this.Result then + this.Result <- value + Unchecked.defaultof<_> (* return value unused in Fold context *) + + override this.OnComplete _ = + if this.State then + invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString + override this.OnDispose () = () }) + + [] + let inline maxBy (f:'T->'U) (source:ISeq<'T>) : 'T when 'U:comparison = + source.Fold (fun _ -> + upcast { new FolderWithPostProcessing<'T,'T,Values>(Unchecked.defaultof<'T>,Values<_,_>(true,Unchecked.defaultof<'U>)) with + override this.ProcessNext value = + match this.State._1, f value with + | true, valueU -> + this.State._1 <- false + this.State._2 <- valueU + this.Result <- value + | false, valueU when valueU > this.State._2 -> + this.State._2 <- valueU + this.Result <- value + | _ -> () + Unchecked.defaultof<_> (* return value unused in Fold context *) + + override this.OnComplete _ = + if this.State._1 then + invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString + override this.OnDispose () = () }) + + [] + let inline min (source:ISeq<'T>) : 'T when 'T:comparison = + source.Fold (fun _ -> + upcast { new FolderWithPostProcessing<'T,'T,bool>(Unchecked.defaultof<'T>,true) with + override this.ProcessNext value = + if this.State then + this.State <- false + this.Result <- value + elif value < this.Result then + this.Result <- value + Unchecked.defaultof<_> (* return value unused in Fold context *) + + override this.OnComplete _ = + if this.State then + invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString + override this.OnDispose () = () }) + + [] + let inline minBy (f:'T->'U) (source:ISeq<'T>) : 'T = + source.Fold (fun _ -> + upcast { new FolderWithPostProcessing<'T,'T,Values>(Unchecked.defaultof<'T>,Values<_,_>(true,Unchecked.defaultof< 'U>)) with + override this.ProcessNext value = + match this.State._1, f value with + | true, valueU -> + this.State._1 <- false + this.State._2 <- valueU + this.Result <- value + | false, valueU when valueU < this.State._2 -> + this.State._2 <- valueU + this.Result <- value + | _ -> () + Unchecked.defaultof<_> (* return value unused in Fold context *) + + override this.OnComplete _ = + if this.State._1 then + invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString + override this.OnDispose () = () }) + + [] + let pairwise (source:ISeq<'T>) : ISeq<'T*'T> = + source.PushTransform { new TransformFactory<'T,'T * 'T>() with + override __.Compose _ _ next = + upcast { new Transform<'T,'U,Values>(next, Values(true, Unchecked.defaultof<'T>)) with + // member this.isFirst = this.State._1 + // member this.lastValue = this.State._2 + override this.ProcessNext (input:'T) : bool = + if this.State._1 then + this.State._2 <- input + this.State._1 <- false + false + else + let currentPair = this.State._2, input + this.State._2 <- input + TailCall.avoid (next.ProcessNext currentPair) }} + + [] + let inline reduce (f:'T->'T->'T) (source: ISeq<'T>) : 'T = + source.Fold (fun _ -> + upcast { new FolderWithPostProcessing<'T,'T,bool>(Unchecked.defaultof<'T>,true) with + override this.ProcessNext value = + if this.State then + this.State <- false + this.Result <- value + else + this.Result <- f this.Result value + Unchecked.defaultof<_> (* return value unused in Fold context *) + + override this.OnComplete _ = + if this.State then + invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString + override this.OnDispose () = () }) + + [] + let inline scan (folder:'State->'T->'State) (initialState:'State) (source:ISeq<'T>) :ISeq<'State> = + source.PushTransform { new TransformFactory<'T,'State>() with + override __.Compose _ _ next = + upcast { new Transform<'T,'V,'State>(next, initialState) with + override this.ProcessNext (input:'T) : bool = + this.State <- folder this.State input + TailCall.avoid (next.ProcessNext this.State) } } + + [] + let skip (skipCount:int) (source:ISeq<'T>) : ISeq<'T> = + source.PushTransform { new TransformFactory<'T,'T>() with + override __.Compose _ _ next = + let mutable this = Unchecked.defaultof> + let skipper = + { new TransformWithPostProcessing<'T,'U,int>(next,(*count*)0) with + // member this.count = this.State + override this.ProcessNext (input:'T) : bool = + if this.State < skipCount then + this.State <- this.State + 1 + false + else + TailCall.avoid (next.ProcessNext input) + + override this.OnComplete _ = + if this.State < skipCount then + let x = skipCount - this.State + invalidOpFmt "{0}\ntried to skip {1} {2} past the end of the seq" + [|SR.GetString SR.notEnoughElements; x; (if x=1 then "element" else "elements")|] + override this.OnDispose () = () + + interface ISkipable with + member __.CanSkip () = + if this.State < skipCount then + this.State <- this.State + 1 + true + else + false } + this <- skipper + upcast this } + + [] + let inline skipWhile (predicate:'T->bool) (source:ISeq<'T>) : ISeq<'T> = + source.PushTransform { new TransformFactory<'T,'T>() with + override __.Compose _ _ next = + upcast { new Transform<'T,'V,bool>(next,true) with + // member this.skip = this.State + override this.ProcessNext (input:'T) : bool = + if this.State then + this.State <- predicate input + if this.State then + false + else + TailCall.avoid (next.ProcessNext input) + else + TailCall.avoid (next.ProcessNext input) }} + + [] + let inline sum (source:ISeq<'T>) = + source.Fold (fun _ -> + upcast { new Folder<'T,'T,NoValue> (LanguagePrimitives.GenericZero,Unchecked.defaultof) with + override this.ProcessNext value = + this.Result <- Checked.(+) this.Result value + Unchecked.defaultof<_> (* return value unused in Fold context *) }) + + [] + let inline sumBy (f:'T->'U) (source:ISeq<'T>) = + source.Fold (fun _ -> + upcast { new Folder<'T,'U,NoValue> (LanguagePrimitives.GenericZero<'U>,Unchecked.defaultof) with + override this.ProcessNext value = + this.Result <- Checked.(+) this.Result (f value) + Unchecked.defaultof<_> (* return value unused in Fold context *) }) + + [] + let take (takeCount:int) (source:ISeq<'T>) : ISeq<'T> = + source.PushTransform { new TransformFactory<'T,'T>() with + member __.Compose outOfBand pipelineIdx next = + upcast { new TransformWithPostProcessing<'T,'U,int>(next,(*count*)0) with + // member this.count = this.State + override this.ProcessNext (input:'T) : bool = + if this.State < takeCount then + this.State <- this.State + 1 + if this.State = takeCount then + outOfBand.StopFurtherProcessing pipelineIdx + TailCall.avoid (next.ProcessNext input) + else + outOfBand.StopFurtherProcessing pipelineIdx + false + + override this.OnComplete terminatingIdx = + if terminatingIdx < pipelineIdx && this.State < takeCount then + let x = takeCount - this.State + invalidOpFmt "tried to take {0} {1} past the end of the seq" + [|SR.GetString SR.notEnoughElements; x; (if x=1 then "element" else "elements")|] + override this.OnDispose () = () }} + + [] + let inline takeWhile (predicate:'T->bool) (source:ISeq<'T>) : ISeq<'T> = + source.PushTransform { new TransformFactory<'T,'T>() with + member __.Compose outOfBand pipeIdx next = + upcast { new Transform<'T,'V,NoValue>(next,Unchecked.defaultof) with + override __.ProcessNext (input:'T) : bool = + if predicate input then + TailCall.avoid (next.ProcessNext input) + else + outOfBand.StopFurtherProcessing pipeIdx + false }} + + [] + let tail (source:ISeq<'T>) : ISeq<'T> = + source.PushTransform { new TransformFactory<'T,'T>() with + member __.Compose _ _ next = + upcast { new TransformWithPostProcessing<'T,'V,bool>(next,true) with + // member this.isFirst = this.State + override this.ProcessNext (input:'T) : bool = + if this.State then + this.State <- false + false + else + TailCall.avoid (next.ProcessNext input) + override this.OnComplete _ = + if this.State then + invalidArg "source" (SR.GetString SR.notEnoughElements) + override this.OnDispose () = () }} + + [] + let truncate (truncateCount:int) (source:ISeq<'T>) : ISeq<'T> = + source.PushTransform { new TransformFactory<'T,'T>() with + member __.Compose outOfBand pipeIdx next = + upcast { new Transform<'T,'U,int>(next,(*count*)0) with + // member this.count = this.State + override this.ProcessNext (input:'T) : bool = + if this.State < truncateCount then + this.State <- this.State + 1 + if this.State = truncateCount then + outOfBand.StopFurtherProcessing pipeIdx + TailCall.avoid (next.ProcessNext input) + else + outOfBand.StopFurtherProcessing pipeIdx + false }} + + [] + let indexed source = + mapi (fun i x -> i,x) source + + [] + let tryItem index (source:ISeq<'T>) = + if index < 0 then None else + source |> skip index |> tryHead + + [] + let inline tryPick f (source:ISeq<'T>) = + source.Fold (fun pipeIdx -> + upcast { new Folder<'T, Option<'U>,NoValue> (None,Unchecked.defaultof) with + override this.ProcessNext value = + match f value with + | (Some _) as some -> + this.Result <- some + this.StopFurtherProcessing pipeIdx + | None -> () + Unchecked.defaultof<_> (* return value unused in Fold context *) }) + + [] + let inline tryFind f (source:ISeq<'T>) = + source.Fold (fun pipeIdx -> + upcast { new Folder<'T, Option<'T>,NoValue> (None,Unchecked.defaultof) with + override this.ProcessNext value = + if f value then + this.Result <- Some value + this.StopFurtherProcessing pipeIdx + Unchecked.defaultof<_> (* return value unused in Fold context *) }) + + [] + let inline tryFindIndex (predicate:'T->bool) (source:ISeq<'T>) : int option = + source.Fold (fun pipeIdx -> + { new Folder<'T, Option, int>(None, 0) with + // member this.index = this.State + override this.ProcessNext value = + if predicate value then + this.Result <- Some this.State + this.StopFurtherProcessing pipeIdx + else + this.State <- this.State + 1 + Unchecked.defaultof<_> (* return value unused in Fold context *) }) + + [] + let tryLast (source:ISeq<'T>) : 'T option = + source.Fold (fun _ -> + upcast { new FolderWithPostProcessing<'T,option<'T>,Values>(None,Values(true, Unchecked.defaultof<'T>)) with + // member this.noItems = this.State._1 + // memebr this.last = this.State._2 + override this.ProcessNext value = + if this.State._1 then + this.State._1 <- false + this.State._2 <- value + Unchecked.defaultof<_> (* return value unused in Fold context *) + override this.OnComplete _ = + if not this.State._1 then + this.Result <- Some this.State._2 + override this.OnDispose () = () }) + + [] + let last (source:ISeq<_>) = + match tryLast source with + | None -> invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString + | Some x -> x + + [] + let windowed (windowSize:int) (source:ISeq<'T>) : ISeq<'T[]> = + source.PushTransform { new TransformFactory<'T,'T[]>() with + member __.Compose outOfBand pipeIdx next = + upcast { + new Transform<'T,'U,Values<'T[],int,int>>(next,Values<'T[],int,int>(Array.zeroCreateUnchecked windowSize, 0, windowSize-1)) with + override this.ProcessNext (input:'T) : bool = + let circularBuffer = this.State._1 + let idx : byref<_> = &this.State._2 + let priming : byref<_> = &this.State._3 + + circularBuffer.[idx] <- input + + idx <- idx + 1 + if idx = windowSize then + idx <- 0 + + if priming > 0 then + priming <- priming - 1 + false + elif windowSize < 32 then + let idx = idx + let window :'T [] = Array.init windowSize (fun i -> circularBuffer.[(idx+i) % windowSize]: 'T) + TailCall.avoid (next.ProcessNext window) + else + let window = Array.zeroCreateUnchecked windowSize + Array.Copy (circularBuffer, idx, window, 0, windowSize - idx) + Array.Copy (circularBuffer, 0, window, windowSize - idx, idx) + TailCall.avoid (next.ProcessNext window) }} + + [] + let concat (sources:ISeq<#ISeq<'T>>) : ISeq<'T> = + Upcast.seq (Enumerable.ConcatEnumerable sources) + + [] + let append (source1:ISeq<'T>) (source2: ISeq<'T>) : ISeq<'T> = + match source1 with + | :? Enumerable.EnumerableBase<'T> as s -> s.Append source2 + | _ -> Upcast.seq (new Enumerable.AppendEnumerable<_>([source2; source1])) + + [] + let delay (delayed:unit->ISeq<'T>) = + Upcast.seq (Enumerable.SeqDelayed (delayed, 1)) + + module internal GroupBy = + let inline private impl (comparer:IEqualityComparer<'SafeKey>) (keyf:'T->'SafeKey) (getKey:'SafeKey->'Key) (source:ISeq<'T>) = + source.Fold (fun _ -> + upcast { new FolderWithPostProcessing<'T,ISeq<'Key*ISeq<'T>>,_>(Unchecked.defaultof<_>,Dictionary comparer) with + override this.ProcessNext v = + let safeKey = keyf v + match this.State.TryGetValue safeKey with + | false, _ -> + let prev = ResizeArray () + this.State.[safeKey] <- prev + prev.Add v + | true, prev -> prev.Add v + Unchecked.defaultof<_> (* return value unused in Fold context *) + + override this.OnComplete _ = + let maxWastage = 4 + for value in this.State.Values do + if value.Capacity - value.Count > maxWastage then value.TrimExcess () + + this.Result <- + this.State + |> ofSeq + |> map (fun kv -> getKey kv.Key, ofResizeArrayUnchecked kv.Value) + + override this.OnDispose () = () }) + + let inline byVal (keyf:'T->'Key) (source:ISeq<'T>) = + delay (fun () -> impl HashIdentity.Structural<'Key> keyf id source) + + let inline byRef (keyf:'T->'Key) (source:ISeq<'T>) = + delay (fun () -> impl (valueComparer<'Key> ()) (keyf >> Value) (fun v -> v._1) source) + + [] + let inline groupByVal<'T,'Key when 'Key : equality and 'Key : struct> (keyf:'T->'Key) (source:ISeq<'T>) = + GroupBy.byVal keyf source + + [] + let inline groupByRef<'T,'Key when 'Key : equality and 'Key : not struct> (keyf:'T->'Key) (source:ISeq<'T>) = + GroupBy.byRef keyf source + + module CountBy = + let inline private impl (comparer:IEqualityComparer<'SafeKey>) (keyf:'T->'SafeKey) (getKey:'SafeKey->'Key) (source:ISeq<'T>) = + source.Fold (fun _ -> + upcast { new FolderWithPostProcessing<'T,ISeq<'Key*int>,_>(Unchecked.defaultof<_>,Dictionary comparer) with + override this.ProcessNext v = + let safeKey = keyf v + this.State.[safeKey] <- + match this.State.TryGetValue safeKey with + | true, prev -> prev + 1 + | false, _ -> 1 + Unchecked.defaultof<_> (* return value unused in Fold context *) + + override this.OnComplete _ = + this.Result <- + this.State + |> ofSeq + |> map (fun group -> getKey group.Key, group.Value) + + override this.OnDispose () = () }) + + let inline byVal (keyf:'T->'Key) (source:ISeq<'T>) = + delay (fun () -> impl HashIdentity.Structural<'Key> keyf id source) + + let inline byRef (keyf:'T->'Key) (source:ISeq<'T>) = + delay (fun () -> impl (valueComparer<'Key> ()) (keyf >> Value) (fun v -> v._1) source) + + [] + let inline countByVal<'T,'Key when 'Key : equality and 'Key : struct> (projection:'T -> 'Key) (source:ISeq<'T>) = + CountBy.byVal projection source + + [] + let inline countByRef<'T,'Key when 'Key : equality and 'Key : not struct> (projection:'T -> 'Key) (source:ISeq<'T>) = + CountBy.byRef projection source + + [] + let toArray (source:ISeq<'T>) = + match box source with + | :? ('T[]) as res -> (res.Clone() :?> 'T[]) + | :? ('T list) as res -> List.toArray res + | :? ICollection<'T> as res -> + // Directly create an array and copy ourselves. + // This avoids an extra copy if using ResizeArray in fallback below. + let arr = Array.zeroCreateUnchecked res.Count + res.CopyTo(arr, 0) + arr + | _ -> + source.Fold (fun _ -> + upcast { new FolderWithPostProcessing<'T,array<'T>,_>(Unchecked.defaultof<_>,ResizeArray ()) with + override this.ProcessNext v = + this.State.Add v + Unchecked.defaultof<_> (* return value unused in Fold context *) + override this.OnComplete _ = + this.Result <- this.State.ToArray () + override this.OnDispose () = () }) + + [] + let sortBy keyf source = + delay (fun () -> + let array = source |> toArray + Array.stableSortInPlaceBy keyf array + Upcast.seq (Array.Enumerable (array, IdentityFactory.Instance, 1))) + + [] + let sort source = + delay (fun () -> + let array = source |> toArray + Array.stableSortInPlace array + Upcast.seq (Array.Enumerable (array, IdentityFactory.Instance, 1))) + + [] + let sortWith f source = + delay (fun () -> + let array = source |> toArray + Array.stableSortInPlaceWith f array + Upcast.seq (Array.Enumerable (array, IdentityFactory.Instance, 1))) + + [] + let rev source = + delay (fun () -> + let array = source |> toArray + Array.Reverse array + Upcast.seq (Array.Enumerable (array, IdentityFactory.Instance, 1))) + + [] + let permute f (source:ISeq<_>) = + delay (fun () -> + source + |> toArray + |> Array.permute f + |> fun array -> Upcast.seq (Array.Enumerable (array, IdentityFactory.Instance, 1))) diff --git a/src/fsharp/FSharp.Core/seqcomposer.fsi b/src/fsharp/FSharp.Core/seqcomposer.fsi new file mode 100644 index 00000000000..1df1b9ee772 --- /dev/null +++ b/src/fsharp/FSharp.Core/seqcomposer.fsi @@ -0,0 +1,344 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.FSharp.Collections + + open System + open System.Collections + open System.Collections.Generic + open Microsoft.FSharp.Core + open Microsoft.FSharp.Collections + + [] + module Composer = + module Core = + [] + type NoValue = struct end + + /// Values is a mutable struct. It can be embedded within the folder type + /// if two values are required for the calculation. + [] + type Value<'a> = + new : a:'a -> Value<'a> + val mutable _1: 'a + + /// Values is a mutable struct. It can be embedded within the folder type + /// if two values are required for the calculation. + [] + type Values<'a,'b> = + new : a:'a * b:'b -> Values<'a,'b> + val mutable _1: 'a + val mutable _2: 'b + + /// Values is a mutable struct. It can be embedded within the folder type + /// if three values are required for the calculation. + [] + type Values<'a,'b,'c> = + new : a:'a * b:'b * c:'c -> Values<'a,'b,'c> + val mutable _1: 'a + val mutable _2: 'b + val mutable _3: 'c + + /// PipeIdx denotes the index of the element within the pipeline. 0 denotes the + /// source of the chain. + type PipeIdx = int + + type IOutOfBand = + abstract StopFurtherProcessing : PipeIdx -> unit + + /// Activity is the root class for chains of activities. It is in a non-generic + /// form so that it can be used by subsequent activities + [] + type Activity = + /// OnComplete is used to determine if the object has been processed correctly, + /// and possibly throw exceptions to denote incorrect application (i.e. such as a Take + /// operation which didn't have a source at least as large as was required). It is + /// not called in the case of an exception being thrown whilst the stream is still + /// being processed. + abstract ChainComplete : stopTailCall:byref*PipeIdx -> unit + /// OnDispose is used to cleanup the stream. It is always called at the last operation + /// after the enumeration has completed. + abstract ChainDispose : stopTailCall:byref -> unit + + /// Activity is the base class of all elements within the pipeline + [] + type Activity<'T,'U> = + inherit Activity + new : unit -> Activity<'T,'U> + abstract member ProcessNext : input:'T -> bool + + [] + type Transform<'T,'U,'State> = + inherit Activity<'T,'U> + new : next:Activity * 'State -> Transform<'T,'U,'State> + val mutable State : 'State + val private Next : Activity + + [] + type TransformWithPostProcessing<'T,'U,'State> = + inherit Transform<'T,'U,'State> + new : next:Activity * 'State -> TransformWithPostProcessing<'T,'U,'State> + abstract OnComplete : PipeIdx -> unit + abstract OnDispose : unit -> unit + + /// Folder is a base class to assist with fold-like operations. It's intended usage + /// is as a base class for an object expression that will be used from within + /// the Fold function. + [] + type Folder<'T,'Result,'State> = + inherit Activity<'T,'T> + new : 'Result*'State -> Folder<'T,'Result,'State> + interface IOutOfBand + val mutable State : 'State + val mutable Result : 'Result + val mutable HaltedIdx : int + member StopFurtherProcessing : PipeIdx -> unit + + [] + type FolderWithPostProcessing<'T,'Result,'State> = + inherit Folder<'T,'Result,'State> + new : 'Result*'State -> FolderWithPostProcessing<'T,'Result,'State> + abstract OnDispose : unit -> unit + abstract OnComplete : PipeIdx -> unit + + [] + type TransformFactory<'T,'U> = + new : unit -> TransformFactory<'T,'U> + abstract member Compose : IOutOfBand -> PipeIdx -> Activity<'U,'V> -> Activity<'T,'V> + + type ISeq<'T> = + inherit System.Collections.Generic.IEnumerable<'T> + abstract member PushTransform : TransformFactory<'T,'U> -> ISeq<'U> + abstract member Fold<'Result,'State> : f:(PipeIdx->Folder<'T,'Result,'State>) -> 'Result + + open Core + + [] + val ofResizeArrayUnchecked : ResizeArray<'T> -> ISeq<'T> + + [] + val ofList : list<'T> -> ISeq<'T> + + [] + val ofArray : array<'T> -> ISeq<'T> + + [] + val ofSeq : seq<'T> -> ISeq<'T> + + [] + val inline average : source: ISeq< ^T> -> ^T + when 'T:(static member Zero : ^T) + and 'T:(static member (+) : ^T * ^T -> ^T) + and ^T:(static member DivideByInt : ^T * int -> ^T) + + [] + val inline averageBy : f:('T -> ^U) -> source:ISeq< 'T > -> ^U + when ^U:(static member Zero : ^U) + and ^U:(static member (+) : ^U * ^U -> ^U) + and ^U:(static member DivideByInt : ^U * int -> ^U) + + [] + val empty<'T> : ISeq<'T> + + [] + val exactlyOne : ISeq<'T> -> 'T + + [] + val inline fold<'T,'State> : f:('State->'T->'State) -> seed:'State -> source:ISeq<'T> -> 'State + + [] + val inline fold2<'T1,'T2,'State> : folder:('State->'T1->'T2->'State) -> state:'State -> source1: ISeq<'T1> -> source2: ISeq<'T2> -> 'State + + [] + val unfold : generator:('State -> option<'T*'State>) -> state:'State -> ISeq<'T> + + [] + val initInfinite : f:(int -> 'T) -> ISeq<'T> + + [] + val init : count:int -> f:(int -> 'T) -> ISeq<'T> + + [] + val inline iter : f:('T -> unit) -> source:ISeq<'T> -> unit + + [] + val inline iter2 : f:('T->'U->unit) -> source1 : ISeq<'T> -> source2 : ISeq<'U> -> unit + + [] + val inline iteri2 : f:(int->'T->'U->unit) -> source1:ISeq<'T> -> source2:ISeq<'U> -> unit + + [] + val tryHead : ISeq<'T> -> option<'T> + + [] + val head: source:ISeq<'T> -> 'T + + [] + val inline iteri : f:(int -> 'T -> unit) -> source:ISeq<'T> -> unit + + [] + val inline except : itemsToExclude:seq<'T> -> source:ISeq<'T> -> ISeq<'T> when 'T:equality + + [] + val inline exists : f:('T -> bool) -> source:ISeq<'T> -> bool + + [] + val inline exists2 : predicate:('T->'U->bool) -> source1:ISeq<'T> -> source2:ISeq<'U> -> bool + + [] + val inline contains : element:'T -> source:ISeq<'T> -> bool when 'T : equality + + [] + val inline forall : f:('T -> bool) -> source:ISeq<'T> -> bool + + [] + val inline forall2 : predicate:('T->'U->bool) -> source1:ISeq<'T> -> source2:ISeq<'U> -> bool + + [] + val inline filter : f:('T -> bool) -> source:ISeq<'T> -> ISeq<'T> + + [] + val inline map : f:('T -> 'U) -> source:ISeq<'T> -> ISeq<'U> + + [] + val inline mapi : f:(int->'a->'b) -> source: ISeq<'a> -> ISeq<'b> + + [] + val inline map2<'T,'U,'V> : map:('T->'U->'V) -> source1:ISeq<'T> -> source2:ISeq<'U> -> ISeq<'V> + + [] + val inline mapi2<'T,'U,'V> : map:(int -> 'T->'U->'V) -> source1:ISeq<'T> -> source2:ISeq<'U> -> ISeq<'V> + + [] + val inline map3<'T,'U,'V,'W> : map:('T->'U->'V->'W) -> source1:ISeq<'T> -> source2:ISeq<'U> -> source3:ISeq<'V> -> ISeq<'W> + + [] + val inline compareWith : f:('T->'T->int) -> source1 :ISeq<'T> -> source2:ISeq<'T> -> int + + [] + val inline choose : f:('a->option<'b>) -> source: ISeq<'a> -> ISeq<'b> + + [] + val inline distinct : source:ISeq<'T> -> ISeq<'T> when 'T:equality + + [] + val inline distinctBy : keyf:('T->'Key) -> source:ISeq<'T> -> ISeq<'T> when 'Key:equality + + [] + val inline max : source:ISeq<'T> -> 'T when 'T:comparison + + [] + val inline maxBy : f:('T->'U) -> source:ISeq<'T> -> 'T when 'U:comparison + + [] + val inline min : source:ISeq<'T> -> 'T when 'T:comparison + + [] + val inline minBy : f:('T->'U) -> source:ISeq<'T> -> 'T when 'U:comparison + + [] + val pairwise : source:ISeq<'T> -> ISeq<'T * 'T> + + [] + val inline reduce : f:('T->'T->'T) -> source:ISeq<'T> -> 'T + + [] + val inline scan : folder:('State->'T->'State) -> initialState:'State -> source:ISeq<'T> -> ISeq<'State> + + [] + val skip : skipCount:int -> source:ISeq<'T> -> ISeq<'T> + + [] + val inline skipWhile : predicate:('T->bool) -> source:ISeq<'T> -> ISeq<'T> + + [] + val inline sum : source:ISeq<'T> -> 'T + when 'T:(static member Zero : ^T) + and 'T:(static member (+) : ^T * ^T -> ^T) + + [] + val inline sumBy : f :('T -> ^U) -> source:ISeq<'T> -> ^U + when ^U:(static member Zero : ^U) + and ^U:(static member (+) : ^U * ^U -> ^U) + + [] + val take : takeCount:int -> source:ISeq<'T> -> ISeq<'T> + + [] + val inline takeWhile : predicate:('T->bool) -> source:ISeq<'T> -> ISeq<'T> + + [] + val tail : source:ISeq<'T> -> ISeq<'T> + + [] + val truncate : truncateCount:int -> source:ISeq<'T> -> ISeq<'T> + + [] + val indexed : source: ISeq<'a> -> ISeq + + [] + val tryItem : index:int -> source:ISeq<'T> -> option<'T> + + [] + val inline tryPick : f:('T -> option<'U>) -> source:ISeq<'T> -> option<'U> + + [] + val inline tryFind : f:('T -> bool) -> source:ISeq<'T> -> option<'T> + + [] + val inline tryFindIndex: predicate:('T->bool) -> source:ISeq<'T> -> option + + [] + val last: source:ISeq<'T> -> 'T + + [] + val tryLast : source:ISeq<'T> -> option<'T> + + [] + val windowed : windowSize:int -> source:ISeq<'T> -> ISeq> + + [] + val concat : sources:ISeq<'Collection> -> ISeq<'T> when 'Collection :> ISeq<'T> + + [] + val append: source1:ISeq<'T> -> source2:ISeq<'T> -> ISeq<'T> + + [] + val delay : (unit -> ISeq<'T>) -> ISeq<'T> + + [] + val inline groupByVal : projection:('T -> 'Key) -> source:ISeq<'T> -> ISeq<'Key * ISeq<'T>> when 'Key : equality and 'Key : struct + + [] + val inline groupByRef : projection:('T -> 'Key) -> source:ISeq<'T> -> ISeq<'Key * ISeq<'T>> when 'Key : equality and 'Key : not struct + + [] + val inline countByVal : projection:('T -> 'Key) -> source:ISeq<'T> -> ISeq<'Key * int> when 'Key : equality and 'Key : struct + + [] + val inline countByRef : projection:('T -> 'Key) -> source:ISeq<'T> -> ISeq<'Key * int> when 'Key : equality and 'Key : not struct + + [] + val toArray: source:ISeq<'T> -> array<'T> + + [] + val sortBy : projection:('T->'Key) -> source:ISeq<'T> -> ISeq<'T> when 'Key : comparison + + [] + val sort : source:ISeq<'T> -> ISeq<'T> when 'T : comparison + + [] + val sortWith : comparer:('T->'T->int) -> source:ISeq<'T> -> ISeq<'T> + + [] + val rev: source:ISeq<'T> -> ISeq<'T> + + [] + val permute: indexMap:(int->int) -> source:ISeq<'T> -> ISeq<'T> + + module internal GroupBy = + val inline byVal : projection:('T -> 'Key) -> source:ISeq<'T> -> ISeq<'Key * ISeq<'T>> when 'Key : equality + val inline byRef : projection:('T -> 'Key) -> source:ISeq<'T> -> ISeq<'Key * ISeq<'T>> when 'Key : equality + + module internal CountBy = + val inline byVal : projection:('T -> 'Key) -> source:ISeq<'T> -> ISeq<'Key * int> when 'Key : equality + val inline byRef : projection:('T -> 'Key) -> source:ISeq<'T> -> ISeq<'Key * int> when 'Key : equality diff --git a/src/fsharp/FSharp.Core/seqcore.fs b/src/fsharp/FSharp.Core/seqcore.fs new file mode 100644 index 00000000000..657c58d1681 --- /dev/null +++ b/src/fsharp/FSharp.Core/seqcore.fs @@ -0,0 +1,405 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.FSharp.Collections + #nowarn "52" // The value has been copied to ensure the original is not mutated by this operation + + open System + open System.Diagnostics + open System.Collections + open System.Collections.Generic + open Microsoft.FSharp.Core + open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators + open Microsoft.FSharp.Core.Operators + open Microsoft.FSharp.Control + open Microsoft.FSharp.Collections + + module internal IEnumerator = + + let noReset() = raise (new System.NotSupportedException(SR.GetString(SR.resetNotSupported))) + let notStarted() = raise (new System.InvalidOperationException(SR.GetString(SR.enumerationNotStarted))) + let alreadyFinished() = raise (new System.InvalidOperationException(SR.GetString(SR.enumerationAlreadyFinished))) + let check started = if not started then notStarted() + let dispose (r : System.IDisposable) = r.Dispose() + + let cast (e : IEnumerator) : IEnumerator<'T> = + { new IEnumerator<'T> with + member x.Current = unbox<'T> e.Current + interface IEnumerator with + member x.Current = unbox<'T> e.Current :> obj + member x.MoveNext() = e.MoveNext() + member x.Reset() = noReset() + interface System.IDisposable with + member x.Dispose() = + match e with + | :? System.IDisposable as e -> e.Dispose() + | _ -> () } + + /// A concrete implementation of an enumerator that returns no values + [] + type EmptyEnumerator<'T>() = + let mutable started = false + interface IEnumerator<'T> with + member x.Current = + check started + (alreadyFinished() : 'T) + + interface System.Collections.IEnumerator with + member x.Current = + check started + (alreadyFinished() : obj) + member x.MoveNext() = + if not started then started <- true + false + member x.Reset() = noReset() + interface System.IDisposable with + member x.Dispose() = () + + let Empty<'T> () = (new EmptyEnumerator<'T>() :> IEnumerator<'T>) + [] + type EmptyEnumerable<'T> = + | EmptyEnumerable + interface IEnumerable<'T> with + member x.GetEnumerator() = Empty<'T>() + interface IEnumerable with + member x.GetEnumerator() = (Empty<'T>() :> IEnumerator) + + let readAndClear r = + lock r (fun () -> match !r with None -> None | Some _ as res -> r := None; res) + + let generateWhileSome openf compute closef : IEnumerator<'U> = + let started = ref false + let curr = ref None + let state = ref (Some(openf())) + let getCurr() = + check !started + match !curr with None -> alreadyFinished() | Some x -> x + let start() = if not !started then (started := true) + + let dispose() = readAndClear state |> Option.iter closef + let finish() = (try dispose() finally curr := None) + { new IEnumerator<'U> with + member x.Current = getCurr() + interface IEnumerator with + member x.Current = box (getCurr()) + member x.MoveNext() = + start() + match !state with + | None -> false (* we started, then reached the end, then got another MoveNext *) + | Some s -> + match (try compute s with e -> finish(); reraise()) with + | None -> finish(); false + | Some _ as x -> curr := x; true + + member x.Reset() = noReset() + interface System.IDisposable with + member x.Dispose() = dispose() } + + [] + type Singleton<'T>(v:'T) = + let mutable started = false + interface IEnumerator<'T> with + member x.Current = v + interface IEnumerator with + member x.Current = box v + member x.MoveNext() = if started then false else (started <- true; true) + member x.Reset() = noReset() + interface System.IDisposable with + member x.Dispose() = () + + let Singleton x = (new Singleton<'T>(x) :> IEnumerator<'T>) + + let EnumerateThenFinally f (e : IEnumerator<'T>) = + { new IEnumerator<'T> with + member x.Current = e.Current + interface IEnumerator with + member x.Current = (e :> IEnumerator).Current + member x.MoveNext() = e.MoveNext() + member x.Reset() = noReset() + interface System.IDisposable with + member x.Dispose() = + try + e.Dispose() + finally + f() + } + + let inline checkNonNull argName arg = + match box arg with + | null -> nullArg argName + | _ -> () + + let mkSeq f = + { new IEnumerable<'U> with + member x.GetEnumerator() = f() + interface IEnumerable with + member x.GetEnumerator() = (f() :> IEnumerator) + } + +namespace Microsoft.FSharp.Core.CompilerServices + + open System + open System.Diagnostics + open Microsoft.FSharp.Core + open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators + open Microsoft.FSharp.Core.Operators + open Microsoft.FSharp.Control + open Microsoft.FSharp.Collections + open Microsoft.FSharp.Primitives.Basics + open System.Collections + open System.Collections.Generic + open Microsoft.FSharp.Collections.IEnumerator + + module RuntimeHelpers = + + [] + type internal StructBox<'T when 'T : equality>(value:'T) = + member x.Value = value + static member Comparer = + let gcomparer = HashIdentity.Structural<'T> + { new IEqualityComparer> with + member __.GetHashCode(v) = gcomparer.GetHashCode(v.Value) + member __.Equals(v1,v2) = gcomparer.Equals(v1.Value,v2.Value) } + + let Generate openf compute closef = + mkSeq (fun () -> IEnumerator.generateWhileSome openf compute closef) + + let GenerateUsing (openf : unit -> ('U :> System.IDisposable)) compute = + Generate openf compute (fun (s:'U) -> s.Dispose()) + + let EnumerateFromFunctions opener moveNext current = + Generate + opener + (fun x -> if moveNext x then Some(current x) else None) + (fun x -> match box(x) with :? System.IDisposable as id -> id.Dispose() | _ -> ()) + + // A family of enumerators that can have additional 'finally' actions added to the enumerator through + // the use of mutation. This is used to 'push' the disposal action for a 'use' into the next enumerator. + // For example, + // seq { use x = ... + // while ... } + // results in the 'while' loop giving an adjustable enumerator. This is then adjusted by adding the disposal action + // from the 'use' into the enumerator. This means that we avoid constructing a two-deep enumerator chain in this + // common case. + type IFinallyEnumerator = + abstract AppendFinallyAction : (unit -> unit) -> unit + + /// A concrete implementation of IEnumerable that adds the given compensation to the "Dispose" chain of any + /// enumerators returned by the enumerable. + [] + type FinallyEnumerable<'T>(compensation: unit -> unit, restf: unit -> seq<'T>) = + interface IEnumerable<'T> with + member x.GetEnumerator() = + try + let ie = restf().GetEnumerator() + match ie with + | :? IFinallyEnumerator as a -> + a.AppendFinallyAction(compensation) + ie + | _ -> + IEnumerator.EnumerateThenFinally compensation ie + with e -> + compensation() + reraise() + interface IEnumerable with + member x.GetEnumerator() = ((x :> IEnumerable<'T>).GetEnumerator() :> IEnumerator) + + /// An optimized object for concatenating a sequence of enumerables + [] + type ConcatEnumerator<'T,'U when 'U :> seq<'T>>(sources: seq<'U>) = + let mutable outerEnum = sources.GetEnumerator() + let mutable currInnerEnum = IEnumerator.Empty() + + let mutable started = false + let mutable finished = false + let mutable compensations = [] + + [] // false = unchecked + val mutable private currElement : 'T + + member x.Finish() = + finished <- true + try + match currInnerEnum with + | null -> () + | _ -> + try + currInnerEnum.Dispose() + finally + currInnerEnum <- null + finally + try + match outerEnum with + | null -> () + | _ -> + try + outerEnum.Dispose() + finally + outerEnum <- null + finally + let rec iter comps = + match comps with + | [] -> () + | h::t -> + try h() finally iter t + try + compensations |> List.rev |> iter + finally + compensations <- [] + + member x.GetCurrent() = + IEnumerator.check started + if finished then IEnumerator.alreadyFinished() else x.currElement + + interface IFinallyEnumerator with + member x.AppendFinallyAction(f) = + compensations <- f :: compensations + + interface IEnumerator<'T> with + member x.Current = x.GetCurrent() + + interface IEnumerator with + member x.Current = box (x.GetCurrent()) + + member x.MoveNext() = + if not started then (started <- true) + if finished then false + else + let rec takeInner () = + // check the inner list + if currInnerEnum.MoveNext() then + x.currElement <- currInnerEnum.Current + true + else + // check the outer list + let rec takeOuter() = + if outerEnum.MoveNext() then + let ie = outerEnum.Current + // Optimization to detect the statically-allocated empty IEnumerables + match box ie with + | :? EmptyEnumerable<'T> -> + // This one is empty, just skip, don't call GetEnumerator, try again + takeOuter() + | _ -> + // OK, this one may not be empty. + // Don't forget to dispose of the enumerator for the inner list now we're done with it + currInnerEnum.Dispose() + currInnerEnum <- ie.GetEnumerator() + takeInner () + else + // We're done + x.Finish() + false + takeOuter() + takeInner () + + member x.Reset() = IEnumerator.noReset() + + interface System.IDisposable with + member x.Dispose() = + if not finished then + x.Finish() + + let EnumerateUsing (resource : 'T :> System.IDisposable) (rest: 'T -> #seq<'U>) = + (FinallyEnumerable((fun () -> match box resource with null -> () | _ -> resource.Dispose()), + (fun () -> rest resource :> seq<_>)) :> seq<_>) + + let mkConcatSeq (sources: seq<'U :> seq<'T>>) = + mkSeq (fun () -> new ConcatEnumerator<_,_>(sources) :> IEnumerator<'T>) + + let EnumerateWhile (g : unit -> bool) (b: seq<'T>) : seq<'T> = + let started = ref false + let curr = ref None + let getCurr() = + IEnumerator.check !started + match !curr with None -> IEnumerator.alreadyFinished() | Some x -> x + let start() = if not !started then (started := true) + + let finish() = (curr := None) + mkConcatSeq + (mkSeq (fun () -> + { new IEnumerator<_> with + member x.Current = getCurr() + interface IEnumerator with + member x.Current = box (getCurr()) + member x.MoveNext() = + start() + let keepGoing = (try g() with e -> finish (); reraise ()) in + if keepGoing then + curr := Some(b); true + else + finish(); false + member x.Reset() = IEnumerator.noReset() + interface System.IDisposable with + member x.Dispose() = () })) + + let EnumerateThenFinally (rest : seq<'T>) (compensation : unit -> unit) = + (FinallyEnumerable(compensation, (fun () -> rest)) :> seq<_>) + + let CreateEvent (add : 'Delegate -> unit) (remove : 'Delegate -> unit) (create : (obj -> 'Args -> unit) -> 'Delegate ) :IEvent<'Delegate,'Args> = + // Note, we implement each interface explicitly: this works around a bug in the CLR + // implementation on CompactFramework 3.7, used on Windows Phone 7 + { new obj() with + member x.ToString() = "" + interface IEvent<'Delegate,'Args> + interface IDelegateEvent<'Delegate> with + member x.AddHandler(h) = add h + member x.RemoveHandler(h) = remove h + interface System.IObservable<'Args> with + member x.Subscribe(r:IObserver<'Args>) = + let h = create (fun _ args -> r.OnNext(args)) + add h + { new System.IDisposable with + member x.Dispose() = remove h } } + + + [] + type GeneratedSequenceBase<'T>() = + let mutable redirectTo : GeneratedSequenceBase<'T> = Unchecked.defaultof<_> + let mutable redirect : bool = false + + abstract GetFreshEnumerator : unit -> IEnumerator<'T> + abstract GenerateNext : next:byref> -> int // 0 = Stop, 1 = Yield, 2 = Goto + abstract Close: unit -> unit + abstract CheckClose: bool + abstract LastGenerated : 'T + + //[] + member x.MoveNextImpl() = + let active = + if redirect then redirectTo + else x + let mutable target = null + match active.GenerateNext(&target) with + | 1 -> + true + | 2 -> + match target.GetEnumerator() with + | :? GeneratedSequenceBase<'T> as g when not active.CheckClose -> + redirectTo <- g + | e -> + redirectTo <- + { new GeneratedSequenceBase<'T>() with + member x.GetFreshEnumerator() = e + member x.GenerateNext(_) = if e.MoveNext() then 1 else 0 + member x.Close() = try e.Dispose() finally active.Close() + member x.CheckClose = true + member x.LastGenerated = e.Current } + redirect <- true + x.MoveNextImpl() + | _ (* 0 *) -> + false + + interface IEnumerable<'T> with + member x.GetEnumerator() = x.GetFreshEnumerator() + interface IEnumerable with + member x.GetEnumerator() = (x.GetFreshEnumerator() :> IEnumerator) + interface IEnumerator<'T> with + member x.Current = if redirect then redirectTo.LastGenerated else x.LastGenerated + member x.Dispose() = if redirect then redirectTo.Close() else x.Close() + interface IEnumerator with + member x.Current = box (if redirect then redirectTo.LastGenerated else x.LastGenerated) + + //[] + member x.MoveNext() = x.MoveNextImpl() + + member x.Reset() = raise <| new System.NotSupportedException() \ No newline at end of file diff --git a/src/fsharp/FSharp.Core/seqcore.fsi b/src/fsharp/FSharp.Core/seqcore.fsi new file mode 100644 index 00000000000..8c915c921cb --- /dev/null +++ b/src/fsharp/FSharp.Core/seqcore.fsi @@ -0,0 +1,150 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.FSharp.Collections + open System + open System.Collections + open System.Collections.Generic + open Microsoft.FSharp.Core + open Microsoft.FSharp.Collections + module internal IEnumerator = + val noReset : unit -> 'a + val notStarted : unit -> 'a + val alreadyFinished : unit -> 'a + val check : started:bool -> unit + val dispose : r:System.IDisposable -> unit + val cast : + e:System.Collections.IEnumerator -> + System.Collections.Generic.IEnumerator<'T> + [] + type EmptyEnumerator<'T> = + class + interface System.IDisposable + interface System.Collections.IEnumerator + interface System.Collections.Generic.IEnumerator<'T> + new : unit -> EmptyEnumerator<'T> + end + val Empty : unit -> System.Collections.Generic.IEnumerator<'T> + [] + type EmptyEnumerable<'T> = + | EmptyEnumerable + with + interface System.Collections.IEnumerable + interface System.Collections.Generic.IEnumerable<'T> + end + + val readAndClear : r:'a option ref -> 'a option + val generateWhileSome : + openf:(unit -> 'a) -> + compute:('a -> 'U option) -> + closef:('a -> unit) -> System.Collections.Generic.IEnumerator<'U> + [] + type Singleton<'T> = + class + interface System.IDisposable + interface System.Collections.IEnumerator + interface System.Collections.Generic.IEnumerator<'T> + new : v:'T -> Singleton<'T> + end + val Singleton : x:'T -> System.Collections.Generic.IEnumerator<'T> + val EnumerateThenFinally : + f:(unit -> unit) -> + e:System.Collections.Generic.IEnumerator<'T> -> + System.Collections.Generic.IEnumerator<'T> + val inline checkNonNull : argName:string -> arg:'a -> unit + val mkSeq : + f:(unit -> System.Collections.Generic.IEnumerator<'U>) -> + System.Collections.Generic.IEnumerable<'U> + +namespace Microsoft.FSharp.Core.CompilerServices + + open System + open System.Collections + open System.Collections.Generic + open Microsoft.FSharp.Core + open Microsoft.FSharp.Collections + + + [] + /// A group of functions used as part of the compiled representation of F# sequence expressions. + module RuntimeHelpers = + + [] + type internal StructBox<'T when 'T : equality> = + new : value:'T -> StructBox<'T> + member Value : 'T + static member Comparer : IEqualityComparer> + + /// The F# compiler emits calls to this function to + /// implement the while operator for F# sequence expressions. + /// + /// A function that indicates whether iteration should continue. + /// The input sequence. + /// + /// The result sequence. + val EnumerateWhile : guard:(unit -> bool) -> source:seq<'T> -> seq<'T> + + /// The F# compiler emits calls to this function to + /// implement the try/finally operator for F# sequence expressions. + /// + /// The input sequence. + /// A computation to be included in an enumerator's Dispose method. + /// + /// The result sequence. + val EnumerateThenFinally : source:seq<'T> -> compensation:(unit -> unit) -> seq<'T> + + /// The F# compiler emits calls to this function to implement the compiler-intrinsic + /// conversions from untyped System.Collections.IEnumerable sequences to typed sequences. + /// + /// An initializer function. + /// A function to iterate and test if end of sequence is reached. + /// A function to retrieve the current element. + /// + /// The resulting typed sequence. + val EnumerateFromFunctions: create:(unit -> 'T) -> moveNext:('T -> bool) -> current:('T -> 'U) -> seq<'U> + + /// The F# compiler emits calls to this function to implement the use operator for F# sequence + /// expressions. + /// + /// The resource to be used and disposed. + /// The input sequence. + /// + /// The result sequence. + val EnumerateUsing : resource:'T -> source:('T -> 'Collection) -> seq<'U> when 'T :> IDisposable and 'Collection :> seq<'U> + + /// Creates an anonymous event with the given handlers. + /// + /// A function to handle adding a delegate for the event to trigger. + /// A function to handle removing a delegate that the event triggers. + /// A function to produce the delegate type the event can trigger. + /// + /// The initialized event. + val CreateEvent : addHandler : ('Delegate -> unit) -> removeHandler : ('Delegate -> unit) -> createHandler : ((obj -> 'Args -> unit) -> 'Delegate) -> Microsoft.FSharp.Control.IEvent<'Delegate,'Args> + + [] + /// The F# compiler emits implementations of this type for compiled sequence expressions. + type GeneratedSequenceBase<'T> = + /// The F# compiler emits implementations of this type for compiled sequence expressions. + /// + /// A new sequence generator for the expression. + new : unit -> GeneratedSequenceBase<'T> + /// The F# compiler emits implementations of this type for compiled sequence expressions. + /// + /// A new enumerator for the sequence. + abstract GetFreshEnumerator : unit -> IEnumerator<'T> + /// The F# compiler emits implementations of this type for compiled sequence expressions. + /// + /// A reference to the sequence. + /// + /// A 0, 1, and 2 respectively indicate Stop, Yield, and Goto conditions for the sequence generator. + abstract GenerateNext : result:byref> -> int + /// The F# compiler emits implementations of this type for compiled sequence expressions. + abstract Close: unit -> unit + /// The F# compiler emits implementations of this type for compiled sequence expressions. + abstract CheckClose: bool + /// The F# compiler emits implementations of this type for compiled sequence expressions. + abstract LastGenerated : 'T + interface IEnumerable<'T> + interface IEnumerable + interface IEnumerator<'T> + interface IEnumerator + diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Aggregates01.il.netfx4.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Aggregates01.il.netfx4.bsl index 97e240269b4..9f4b80a6edf 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Aggregates01.il.netfx4.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Linq101Aggregates01.il.netfx4.bsl @@ -38,20 +38,20 @@ } .mresource public FSharpSignatureData.Linq101Aggregates01 { - // Offset: 0x00000000 Length: 0x0000060C + // Offset: 0x00000000 Length: 0x000005FA } .mresource public FSharpOptimizationData.Linq101Aggregates01 { - // Offset: 0x00000610 Length: 0x00000211 + // Offset: 0x00000600 Length: 0x00000211 } .module Linq101Aggregates01.exe -// MVID: {58067926-D281-4783-A745-038326790658} +// MVID: {581D1D27-D281-4783-A745-0383271D1D58} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00AC0000 +// Image base: 0x02BA0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -116,7 +116,7 @@ // Code size 196 (0xc4) .maxstack 6 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 100001,100001 : 0,0 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Aggregates01.fs' + .line 100001,100001 : 0,0 'C:\\src\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\QueryExpressionStepping\\Linq101Aggregates01.fs' IL_0000: ldarg.0 IL_0001: ldfld int32 Linq101Aggregates01/uniqueFactors@12::pc IL_0006: ldc.i4.1 @@ -823,6 +823,90 @@ } // end of class 'numSum@22-1' + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'numSum@22-3' + extends class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2 + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + // Code size 18 (0x12) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 Linq101Aggregates01/'numSum@22-3'::f + IL_0007: nop + IL_0008: ldarg.0 + IL_0009: ldc.i4.0 + IL_000a: callvirt instance void class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2::.ctor(!1) + IL_000f: ldarg.0 + IL_0010: pop + IL_0011: ret + } // end of method 'numSum@22-3'::.ctor + + .method public hidebysig virtual instance bool + ProcessNext(int32 input) cil managed + { + // Code size 28 (0x1c) + .maxstack 8 + .line 22,22 : 9,16 '' + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: ldfld !1 class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2::Value + IL_0007: ldarg.0 + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 Linq101Aggregates01/'numSum@22-3'::f + IL_000d: ldarg.1 + IL_000e: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0013: add.ovf + IL_0014: stfld !1 class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2::Value + IL_0019: nop + IL_001a: ldc.i4.0 + IL_001b: ret + } // end of method 'numSum@22-3'::ProcessNext + + } // end of class 'numSum@22-3' + + .class auto ansi serializable nested assembly beforefieldinit 'numSum@22-2' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2> + { + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname + instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 Linq101Aggregates01/'numSum@22-2'::f + IL_000d: ret + } // end of method 'numSum@22-2'::.ctor + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2 + Invoke(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 _arg1) cil managed + { + // Code size 13 (0xd) + .maxstack 8 + .line 22,22 : 9,16 '' + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 Linq101Aggregates01/'numSum@22-2'::f + IL_0007: newobj instance void Linq101Aggregates01/'numSum@22-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) + IL_000c: ret + } // end of method 'numSum@22-2'::Invoke + + } // end of class 'numSum@22-2' + .class auto autochar serializable sealed nested assembly beforefieldinit specialname totalChars@30 extends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1 { @@ -1219,6 +1303,90 @@ } // end of class 'totalChars@31-1' + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'totalChars@31-3' + extends class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2 + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + // Code size 18 (0x12) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 Linq101Aggregates01/'totalChars@31-3'::f + IL_0007: nop + IL_0008: ldarg.0 + IL_0009: ldc.i4.0 + IL_000a: callvirt instance void class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2::.ctor(!1) + IL_000f: ldarg.0 + IL_0010: pop + IL_0011: ret + } // end of method 'totalChars@31-3'::.ctor + + .method public hidebysig virtual instance bool + ProcessNext(string input) cil managed + { + // Code size 28 (0x1c) + .maxstack 8 + .line 31,31 : 9,25 '' + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: ldfld !1 class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2::Value + IL_0007: ldarg.0 + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 Linq101Aggregates01/'totalChars@31-3'::f + IL_000d: ldarg.1 + IL_000e: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0013: add.ovf + IL_0014: stfld !1 class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2::Value + IL_0019: nop + IL_001a: ldc.i4.0 + IL_001b: ret + } // end of method 'totalChars@31-3'::ProcessNext + + } // end of class 'totalChars@31-3' + + .class auto ansi serializable nested assembly beforefieldinit 'totalChars@31-2' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2> + { + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname + instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 Linq101Aggregates01/'totalChars@31-2'::f + IL_000d: ret + } // end of method 'totalChars@31-2'::.ctor + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2 + Invoke(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 _arg1) cil managed + { + // Code size 13 (0xd) + .maxstack 8 + .line 31,31 : 9,25 '' + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 Linq101Aggregates01/'totalChars@31-2'::f + IL_0007: newobj instance void Linq101Aggregates01/'totalChars@31-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) + IL_000c: ret + } // end of method 'totalChars@31-2'::Invoke + + } // end of class 'totalChars@31-2' + .class auto ansi serializable nested assembly beforefieldinit categories@39 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { @@ -1723,6 +1891,90 @@ } // end of class 'sum@43-1' + .class auto autochar serializable sealed nested assembly beforefieldinit specialname 'sum@43-3' + extends class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2 + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname + instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + // Code size 18 (0x12) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 Linq101Aggregates01/'sum@43-3'::f + IL_0007: nop + IL_0008: ldarg.0 + IL_0009: ldc.i4.0 + IL_000a: callvirt instance void class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2::.ctor(!1) + IL_000f: ldarg.0 + IL_0010: pop + IL_0011: ret + } // end of method 'sum@43-3'::.ctor + + .method public hidebysig virtual instance bool + ProcessNext(class [Utils]Utils/Product input) cil managed + { + // Code size 28 (0x1c) + .maxstack 8 + .line 43,43 : 13,33 '' + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: ldfld !1 class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2::Value + IL_0007: ldarg.0 + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 Linq101Aggregates01/'sum@43-3'::f + IL_000d: ldarg.1 + IL_000e: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_0013: add.ovf + IL_0014: stfld !1 class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2::Value + IL_0019: nop + IL_001a: ldc.i4.0 + IL_001b: ret + } // end of method 'sum@43-3'::ProcessNext + + } // end of class 'sum@43-3' + + .class auto ansi serializable nested assembly beforefieldinit 'sum@43-2' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2> + { + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname + instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 f) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 Linq101Aggregates01/'sum@43-2'::f + IL_000d: ret + } // end of method 'sum@43-2'::.ctor + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2 + Invoke(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 _arg1) cil managed + { + // Code size 13 (0xd) + .maxstack 8 + .line 43,43 : 13,33 '' + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 Linq101Aggregates01/'sum@43-2'::f + IL_0007: newobj instance void Linq101Aggregates01/'sum@43-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) + IL_000c: ret + } // end of method 'sum@43-2'::Invoke + + } // end of class 'sum@43-2' + .class auto ansi serializable nested assembly beforefieldinit 'categories@40-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,int32>,object>> { @@ -1745,7 +1997,7 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,int32>,object> Invoke(class [System.Core]System.Linq.IGrouping`2 _arg2) cil managed { - // Code size 169 (0xa9) + // Code size 116 (0x74) .maxstack 10 .locals init ([0] class [System.Core]System.Linq.IGrouping`2 g, [1] int32 sum, @@ -1755,10 +2007,7 @@ [5] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 V_5, [6] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_6, [7] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_7, - [8] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_8, - [9] int32 V_9, - [10] int32 V_10, - [11] class [mscorlib]System.IDisposable V_11) + [8] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2> V_8) .line 40,40 : 38,39 '' IL_0000: nop IL_0001: ldarg.1 @@ -1793,70 +2042,25 @@ IL_0039: ldloc.s V_5 IL_003b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() IL_0040: stloc.s V_7 - IL_0042: ldloc.s V_7 - IL_0044: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0042: ldloc.s V_6 + IL_0044: newobj instance void Linq101Aggregates01/'sum@43-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) IL_0049: stloc.s V_8 - .try - { - IL_004b: ldc.i4.0 - IL_004c: stloc.s V_10 - IL_004e: ldloc.s V_8 - IL_0050: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_0055: brfalse.s IL_006d - - .line 43,43 : 13,33 '' - IL_0057: ldloc.s V_10 - IL_0059: ldloc.s V_6 - IL_005b: ldloc.s V_8 - IL_005d: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0062: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0067: add.ovf - IL_0068: stloc.s V_10 - .line 100001,100001 : 0,0 '' - IL_006a: nop - IL_006b: br.s IL_004e - - IL_006d: ldloc.s V_10 - IL_006f: stloc.s V_9 - IL_0071: leave.s IL_0091 - - } // end .try - finally - { - IL_0073: ldloc.s V_8 - IL_0075: isinst [mscorlib]System.IDisposable - IL_007a: stloc.s V_11 - IL_007c: ldloc.s V_11 - IL_007e: brfalse.s IL_0082 - - IL_0080: br.s IL_0084 - - IL_0082: br.s IL_008e - - .line 100001,100001 : 0,0 '' - IL_0084: ldloc.s V_11 - IL_0086: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_008b: ldnull - IL_008c: pop - IL_008d: endfinally - .line 100001,100001 : 0,0 '' - IL_008e: ldnull - IL_008f: pop - IL_0090: endfinally - .line 100001,100001 : 0,0 '' - } // end handler - IL_0091: ldloc.s V_9 - IL_0093: stloc.1 + IL_004b: ldloc.s V_7 + IL_004d: call class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/ISeq`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToComposer(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0052: ldloc.s V_8 + IL_0054: callvirt instance !!0 class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/ISeq`1::ForEach>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,!!0>) + IL_0059: ldfld !1 class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2::Value + IL_005e: stloc.1 .line 45,45 : 9,28 '' - IL_0094: ldarg.0 - IL_0095: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'categories@40-3'::builder@ - IL_009a: ldloc.0 - IL_009b: ldloc.1 - IL_009c: newobj instance void class [mscorlib]System.Tuple`2,int32>::.ctor(!0, + IL_005f: ldarg.0 + IL_0060: ldfld class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder Linq101Aggregates01/'categories@40-3'::builder@ + IL_0065: ldloc.0 + IL_0066: ldloc.1 + IL_0067: newobj instance void class [mscorlib]System.Tuple`2,int32>::.ctor(!0, !1) - IL_00a1: tail. - IL_00a3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,int32>,object>(!!0) - IL_00a8: ret + IL_006c: tail. + IL_006e: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Yield,int32>,object>(!!0) + IL_0073: ret } // end of method 'categories@40-3'::Invoke } // end of class 'categories@40-3' @@ -7987,7 +8191,7 @@ .method public static void main@() cil managed { .entrypoint - // Code size 1965 (0x7ad) + // Code size 1859 (0x743) .maxstack 13 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 factorsOf300, [1] int32 uniqueFactors, @@ -8016,56 +8220,50 @@ [24] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 V_24, [25] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_25, [26] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_26, - [27] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_27, - [28] int32 V_28, - [29] int32 V_29, - [30] class [mscorlib]System.IDisposable V_30, - [31] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_31, - [32] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_32, - [33] class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_33, - [34] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 V_34, - [35] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_35, - [36] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_36, - [37] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_37, - [38] int32 V_38, - [39] int32 V_39, - [40] class [mscorlib]System.IDisposable V_40, + [27] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2> V_27, + [28] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_28, + [29] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_29, + [30] class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_30, + [31] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 V_31, + [32] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_32, + [33] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_33, + [34] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2> V_34, + [35] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_35, + [36] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_36, + [37] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_37, + [38] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_38, + [39] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_39, + [40] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_40, [41] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_41, [42] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_42, [43] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_43, [44] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_44, [45] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_45, - [46] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_46, - [47] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_47, - [48] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_48, - [49] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_49, - [50] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_50, - [51] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_51, - [52] class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_52, - [53] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 V_53, - [54] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_54, - [55] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_55, - [56] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_56, - [57] float64 V_57, - [58] float64 V_58, - [59] int32 V_59, - [60] float64 V_60, - [61] int32 V_61, - [62] class [mscorlib]System.IDisposable V_62, - [63] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_63, - [64] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_64, - [65] class [mscorlib]System.Tuple`2,class [mscorlib]System.Collections.IEnumerable>,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64>> V_65, - [66] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable> V_66, - [67] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64> V_67, - [68] class [mscorlib]System.Collections.Generic.IEnumerable`1> V_68, - [69] class [mscorlib]System.Collections.Generic.IEnumerator`1> V_69, - [70] float64 V_70, - [71] float64 V_71, - [72] int32 V_72, - [73] float64 V_73, - [74] int32 V_74, - [75] class [mscorlib]System.IDisposable V_75, - [76] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_76) + [46] class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_46, + [47] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 V_47, + [48] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_48, + [49] class [mscorlib]System.Collections.Generic.IEnumerable`1 V_49, + [50] class [mscorlib]System.Collections.Generic.IEnumerator`1 V_50, + [51] float64 V_51, + [52] float64 V_52, + [53] int32 V_53, + [54] float64 V_54, + [55] int32 V_55, + [56] class [mscorlib]System.IDisposable V_56, + [57] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_57, + [58] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_58, + [59] class [mscorlib]System.Tuple`2,class [mscorlib]System.Collections.IEnumerable>,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64>> V_59, + [60] class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable> V_60, + [61] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64> V_61, + [62] class [mscorlib]System.Collections.Generic.IEnumerable`1> V_62, + [63] class [mscorlib]System.Collections.Generic.IEnumerator`1> V_63, + [64] float64 V_64, + [65] float64 V_65, + [66] int32 V_66, + [67] float64 V_67, + [68] int32 V_68, + [69] class [mscorlib]System.IDisposable V_69, + [70] class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder V_70) .line 8,8 : 1,31 '' IL_0000: nop IL_0001: ldc.i4.2 @@ -8171,739 +8369,649 @@ IL_00da: ldloc.s V_24 IL_00dc: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() IL_00e1: stloc.s V_26 - IL_00e3: ldloc.s V_26 - IL_00e5: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_00e3: ldloc.s V_25 + IL_00e5: newobj instance void Linq101Aggregates01/'numSum@22-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) IL_00ea: stloc.s V_27 - .try - { - IL_00ec: ldc.i4.0 - IL_00ed: stloc.s V_29 - IL_00ef: ldloc.s V_27 - IL_00f1: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_00f6: brfalse.s IL_010e - - .line 22,22 : 9,16 '' - IL_00f8: ldloc.s V_29 - IL_00fa: ldloc.s V_25 - IL_00fc: ldloc.s V_27 - IL_00fe: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_0103: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_0108: add.ovf - IL_0109: stloc.s V_29 - .line 100001,100001 : 0,0 '' - IL_010b: nop - IL_010c: br.s IL_00ef - - IL_010e: ldloc.s V_29 - IL_0110: stloc.s V_28 - IL_0112: leave.s IL_0132 - - } // end .try - finally - { - IL_0114: ldloc.s V_27 - IL_0116: isinst [mscorlib]System.IDisposable - IL_011b: stloc.s V_30 - IL_011d: ldloc.s V_30 - IL_011f: brfalse.s IL_0123 - - IL_0121: br.s IL_0125 - - IL_0123: br.s IL_012f - - .line 100001,100001 : 0,0 '' - IL_0125: ldloc.s V_30 - IL_0127: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_012c: ldnull - IL_012d: pop - IL_012e: endfinally - .line 100001,100001 : 0,0 '' - IL_012f: ldnull - IL_0130: pop - IL_0131: endfinally - .line 100001,100001 : 0,0 '' - } // end handler - IL_0132: ldloc.s V_28 - IL_0134: dup - IL_0135: stsfld int32 ''.$Linq101Aggregates01::numSum@19 - IL_013a: stloc.3 + IL_00ec: ldloc.s V_26 + IL_00ee: call class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/ISeq`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToComposer(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_00f3: ldloc.s V_27 + IL_00f5: callvirt instance !!0 class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/ISeq`1::ForEach>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,!!0>) + IL_00fa: ldfld !1 class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2::Value + IL_00ff: dup + IL_0100: stsfld int32 ''.$Linq101Aggregates01::numSum@19 + IL_0105: stloc.3 .line 26,26 : 1,45 '' - IL_013b: ldstr "cherry" - IL_0140: ldstr "apple" - IL_0145: ldstr "blueberry" - IL_014a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() - IL_014f: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_0106: ldstr "cherry" + IL_010b: ldstr "apple" + IL_0110: ldstr "blueberry" + IL_0115: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_011a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0154: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_011f: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0159: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_0124: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_015e: dup - IL_015f: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Aggregates01::words@26 - IL_0164: stloc.s words - IL_0166: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_016b: stloc.s V_31 - IL_016d: ldloc.s V_31 - IL_016f: stloc.s V_32 - IL_0171: ldnull - IL_0172: ldnull - IL_0173: ldnull - IL_0174: ldc.i4.0 - IL_0175: ldnull - IL_0176: newobj instance void Linq101Aggregates01/totalChars@30::.ctor(string, + IL_0129: dup + IL_012a: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Aggregates01::words@26 + IL_012f: stloc.s words + IL_0131: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0136: stloc.s V_28 + IL_0138: ldloc.s V_28 + IL_013a: stloc.s V_29 + IL_013c: ldnull + IL_013d: ldnull + IL_013e: ldnull + IL_013f: ldc.i4.0 + IL_0140: ldnull + IL_0141: newobj instance void Linq101Aggregates01/totalChars@30::.ctor(string, string, class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, string) - IL_017b: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0180: newobj instance void Linq101Aggregates01/'totalChars@31-1'::.ctor() - IL_0185: newobj instance void class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor(!0, + IL_0146: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_014b: newobj instance void Linq101Aggregates01/'totalChars@31-1'::.ctor() + IL_0150: newobj instance void class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor(!0, !1) - IL_018a: stloc.s V_33 - IL_018c: ldloc.s V_33 - IL_018e: call instance !0 class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::get_Item1() - IL_0193: stloc.s V_34 - IL_0195: ldloc.s V_33 - IL_0197: call instance !1 class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::get_Item2() - IL_019c: stloc.s V_35 - IL_019e: ldloc.s V_34 - IL_01a0: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_01a5: stloc.s V_36 - IL_01a7: ldloc.s V_36 - IL_01a9: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_01ae: stloc.s V_37 - .try - { - IL_01b0: ldc.i4.0 - IL_01b1: stloc.s V_39 - IL_01b3: ldloc.s V_37 - IL_01b5: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_01ba: brfalse.s IL_01d2 - - .line 31,31 : 9,25 '' - IL_01bc: ldloc.s V_39 - IL_01be: ldloc.s V_35 - IL_01c0: ldloc.s V_37 - IL_01c2: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_01c7: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_01cc: add.ovf - IL_01cd: stloc.s V_39 - .line 100001,100001 : 0,0 '' - IL_01cf: nop - IL_01d0: br.s IL_01b3 - - IL_01d2: ldloc.s V_39 - IL_01d4: stloc.s V_38 - IL_01d6: leave.s IL_01f6 - - } // end .try - finally - { - IL_01d8: ldloc.s V_37 - IL_01da: isinst [mscorlib]System.IDisposable - IL_01df: stloc.s V_40 - IL_01e1: ldloc.s V_40 - IL_01e3: brfalse.s IL_01e7 - - IL_01e5: br.s IL_01e9 - - IL_01e7: br.s IL_01f3 - - .line 100001,100001 : 0,0 '' - IL_01e9: ldloc.s V_40 - IL_01eb: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_01f0: ldnull - IL_01f1: pop - IL_01f2: endfinally - .line 100001,100001 : 0,0 '' - IL_01f3: ldnull - IL_01f4: pop - IL_01f5: endfinally - .line 100001,100001 : 0,0 '' - } // end handler - IL_01f6: ldloc.s V_38 - IL_01f8: dup - IL_01f9: stsfld int32 ''.$Linq101Aggregates01::totalChars@28 - IL_01fe: stloc.s totalChars + IL_0155: stloc.s V_30 + IL_0157: ldloc.s V_30 + IL_0159: call instance !0 class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::get_Item1() + IL_015e: stloc.s V_31 + IL_0160: ldloc.s V_30 + IL_0162: call instance !1 class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::get_Item2() + IL_0167: stloc.s V_32 + IL_0169: ldloc.s V_31 + IL_016b: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_0170: stloc.s V_33 + IL_0172: ldloc.s V_32 + IL_0174: newobj instance void Linq101Aggregates01/'totalChars@31-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) + IL_0179: stloc.s V_34 + IL_017b: ldloc.s V_33 + IL_017d: call class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/ISeq`1 [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToComposer(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0182: ldloc.s V_34 + IL_0184: callvirt instance !!0 class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/ISeq`1::ForEach>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,!!0>) + IL_0189: ldfld !1 class [FSharp.Core]Microsoft.FSharp.Collections.ComposerModule/Core/Folder`2::Value + IL_018e: dup + IL_018f: stsfld int32 ''.$Linq101Aggregates01::totalChars@28 + IL_0194: stloc.s totalChars .line 35,35 : 1,32 '' - IL_0200: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() - IL_0205: dup - IL_0206: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Aggregates01::products@35 - IL_020b: stloc.s products + IL_0196: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 [Utils]Utils::getProductList() + IL_019b: dup + IL_019c: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Aggregates01::products@35 + IL_01a1: stloc.s products .line 37,46 : 1,21 '' - IL_020d: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0212: stloc.s V_41 - IL_0214: ldloc.s V_41 - IL_0216: ldloc.s V_41 - IL_0218: ldloc.s V_41 - IL_021a: ldloc.s V_41 - IL_021c: ldloc.s V_41 - IL_021e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() - IL_0223: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 - IL_0228: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_022d: ldloc.s V_41 - IL_022f: newobj instance void Linq101Aggregates01/categories@39::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0234: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01a3: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_01a8: stloc.s V_35 + IL_01aa: ldloc.s V_35 + IL_01ac: ldloc.s V_35 + IL_01ae: ldloc.s V_35 + IL_01b0: ldloc.s V_35 + IL_01b2: ldloc.s V_35 + IL_01b4: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() + IL_01b9: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 + IL_01be: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_01c3: ldloc.s V_35 + IL_01c5: newobj instance void Linq101Aggregates01/categories@39::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_01ca: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0239: newobj instance void Linq101Aggregates01/'categories@40-1'::.ctor() - IL_023e: newobj instance void Linq101Aggregates01/'categories@40-2'::.ctor() - IL_0243: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01cf: newobj instance void Linq101Aggregates01/'categories@40-1'::.ctor() + IL_01d4: newobj instance void Linq101Aggregates01/'categories@40-2'::.ctor() + IL_01d9: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0248: ldloc.s V_41 - IL_024a: newobj instance void Linq101Aggregates01/'categories@40-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_024f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,int32>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01de: ldloc.s V_35 + IL_01e0: newobj instance void Linq101Aggregates01/'categories@40-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_01e5: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,int32>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0254: newobj instance void Linq101Aggregates01/'categories@45-4'::.ctor() - IL_0259: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,int32>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_01ea: newobj instance void Linq101Aggregates01/'categories@45-4'::.ctor() + IL_01ef: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,int32>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_025e: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_0263: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0268: dup - IL_0269: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories@37 - IL_026e: stloc.s categories - IL_0270: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0275: stloc.s V_42 - IL_0277: ldloc.s V_42 - IL_0279: ldc.i4.0 - IL_027a: ldc.i4.0 - IL_027b: ldnull - IL_027c: ldc.i4.0 - IL_027d: ldc.i4.0 - IL_027e: newobj instance void Linq101Aggregates01/minNum@49::.ctor(int32, + IL_01f4: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_01f9: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_01fe: dup + IL_01ff: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories@37 + IL_0204: stloc.s categories + IL_0206: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_020b: stloc.s V_36 + IL_020d: ldloc.s V_36 + IL_020f: ldc.i4.0 + IL_0210: ldc.i4.0 + IL_0211: ldnull + IL_0212: ldc.i4.0 + IL_0213: ldc.i4.0 + IL_0214: newobj instance void Linq101Aggregates01/minNum@49::.ctor(int32, int32, class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, int32) - IL_0283: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0288: newobj instance void Linq101Aggregates01/'minNum@49-1'::.ctor() - IL_028d: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MinBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0219: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_021e: newobj instance void Linq101Aggregates01/'minNum@49-1'::.ctor() + IL_0223: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MinBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0292: dup - IL_0293: stsfld int32 ''.$Linq101Aggregates01::minNum@49 - IL_0298: stloc.s minNum - IL_029a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_029f: stloc.s V_43 - IL_02a1: ldloc.s V_43 - IL_02a3: ldnull - IL_02a4: ldnull - IL_02a5: ldnull - IL_02a6: ldc.i4.0 - IL_02a7: ldnull - IL_02a8: newobj instance void Linq101Aggregates01/shortestWord@52::.ctor(string, + IL_0228: dup + IL_0229: stsfld int32 ''.$Linq101Aggregates01::minNum@49 + IL_022e: stloc.s minNum + IL_0230: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0235: stloc.s V_37 + IL_0237: ldloc.s V_37 + IL_0239: ldnull + IL_023a: ldnull + IL_023b: ldnull + IL_023c: ldc.i4.0 + IL_023d: ldnull + IL_023e: newobj instance void Linq101Aggregates01/shortestWord@52::.ctor(string, string, class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, string) - IL_02ad: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_02b2: newobj instance void Linq101Aggregates01/'shortestWord@52-1'::.ctor() - IL_02b7: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MinBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0243: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0248: newobj instance void Linq101Aggregates01/'shortestWord@52-1'::.ctor() + IL_024d: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MinBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_02bc: dup - IL_02bd: stsfld int32 ''.$Linq101Aggregates01::shortestWord@52 - IL_02c2: stloc.s shortestWord + IL_0252: dup + IL_0253: stsfld int32 ''.$Linq101Aggregates01::shortestWord@52 + IL_0258: stloc.s shortestWord .line 55,61 : 1,21 '' - IL_02c4: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_02c9: stloc.s V_44 - IL_02cb: ldloc.s V_44 - IL_02cd: ldloc.s V_44 - IL_02cf: ldloc.s V_44 - IL_02d1: ldloc.s V_44 - IL_02d3: ldloc.s V_44 - IL_02d5: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() - IL_02da: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 - IL_02df: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_02e4: ldloc.s V_44 - IL_02e6: newobj instance void Linq101Aggregates01/categories2@57::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_02eb: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_025a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_025f: stloc.s V_38 + IL_0261: ldloc.s V_38 + IL_0263: ldloc.s V_38 + IL_0265: ldloc.s V_38 + IL_0267: ldloc.s V_38 + IL_0269: ldloc.s V_38 + IL_026b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() + IL_0270: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 + IL_0275: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_027a: ldloc.s V_38 + IL_027c: newobj instance void Linq101Aggregates01/categories2@57::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0281: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_02f0: newobj instance void Linq101Aggregates01/'categories2@58-1'::.ctor() - IL_02f5: newobj instance void Linq101Aggregates01/'categories2@58-2'::.ctor() - IL_02fa: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0286: newobj instance void Linq101Aggregates01/'categories2@58-1'::.ctor() + IL_028b: newobj instance void Linq101Aggregates01/'categories2@58-2'::.ctor() + IL_0290: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_02ff: ldloc.s V_44 - IL_0301: newobj instance void Linq101Aggregates01/'categories2@58-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0306: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0295: ldloc.s V_38 + IL_0297: newobj instance void Linq101Aggregates01/'categories2@58-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_029c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_030b: newobj instance void Linq101Aggregates01/'categories2@60-4'::.ctor() - IL_0310: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_02a1: newobj instance void Linq101Aggregates01/'categories2@60-4'::.ctor() + IL_02a6: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0315: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_031a: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_031f: dup - IL_0320: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories2@55 - IL_0325: stloc.s categories2 + IL_02ab: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_02b0: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_02b5: dup + IL_02b6: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories2@55 + IL_02bb: stloc.s categories2 .line 64,71 : 1,21 '' - IL_0327: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_032c: stloc.s V_45 - IL_032e: ldloc.s V_45 - IL_0330: ldloc.s V_45 - IL_0332: ldloc.s V_45 - IL_0334: ldloc.s V_45 - IL_0336: ldloc.s V_45 - IL_0338: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() - IL_033d: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 - IL_0342: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0347: ldloc.s V_45 - IL_0349: newobj instance void Linq101Aggregates01/categories3@66::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_034e: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_02bd: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_02c2: stloc.s V_39 + IL_02c4: ldloc.s V_39 + IL_02c6: ldloc.s V_39 + IL_02c8: ldloc.s V_39 + IL_02ca: ldloc.s V_39 + IL_02cc: ldloc.s V_39 + IL_02ce: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() + IL_02d3: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 + IL_02d8: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_02dd: ldloc.s V_39 + IL_02df: newobj instance void Linq101Aggregates01/categories3@66::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_02e4: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0353: newobj instance void Linq101Aggregates01/'categories3@67-1'::.ctor() - IL_0358: newobj instance void Linq101Aggregates01/'categories3@67-2'::.ctor() - IL_035d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_02e9: newobj instance void Linq101Aggregates01/'categories3@67-1'::.ctor() + IL_02ee: newobj instance void Linq101Aggregates01/'categories3@67-2'::.ctor() + IL_02f3: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0362: ldloc.s V_45 - IL_0364: newobj instance void Linq101Aggregates01/'categories3@67-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0369: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_02f8: ldloc.s V_39 + IL_02fa: newobj instance void Linq101Aggregates01/'categories3@67-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_02ff: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_036e: newobj instance void Linq101Aggregates01/'categories3@70-4'::.ctor() - IL_0373: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0304: newobj instance void Linq101Aggregates01/'categories3@70-4'::.ctor() + IL_0309: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0378: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_037d: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0382: dup - IL_0383: stsfld class [mscorlib]System.Tuple`2>[] ''.$Linq101Aggregates01::categories3@64 - IL_0388: stloc.s categories3 - IL_038a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_038f: stloc.s V_46 - IL_0391: ldloc.s V_46 - IL_0393: ldc.i4.0 - IL_0394: ldc.i4.0 - IL_0395: ldnull - IL_0396: ldc.i4.0 - IL_0397: ldc.i4.0 - IL_0398: newobj instance void Linq101Aggregates01/maxNum@74::.ctor(int32, + IL_030e: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_0313: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0318: dup + IL_0319: stsfld class [mscorlib]System.Tuple`2>[] ''.$Linq101Aggregates01::categories3@64 + IL_031e: stloc.s categories3 + IL_0320: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0325: stloc.s V_40 + IL_0327: ldloc.s V_40 + IL_0329: ldc.i4.0 + IL_032a: ldc.i4.0 + IL_032b: ldnull + IL_032c: ldc.i4.0 + IL_032d: ldc.i4.0 + IL_032e: newobj instance void Linq101Aggregates01/maxNum@74::.ctor(int32, int32, class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, int32) - IL_039d: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_03a2: newobj instance void Linq101Aggregates01/'maxNum@74-1'::.ctor() - IL_03a7: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MaxBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0333: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0338: newobj instance void Linq101Aggregates01/'maxNum@74-1'::.ctor() + IL_033d: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MaxBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_03ac: dup - IL_03ad: stsfld int32 ''.$Linq101Aggregates01::maxNum@74 - IL_03b2: stloc.s maxNum - IL_03b4: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_03b9: stloc.s V_47 - IL_03bb: ldloc.s V_47 - IL_03bd: ldnull - IL_03be: ldnull - IL_03bf: ldnull - IL_03c0: ldc.i4.0 - IL_03c1: ldnull - IL_03c2: newobj instance void Linq101Aggregates01/longestLength@77::.ctor(string, + IL_0342: dup + IL_0343: stsfld int32 ''.$Linq101Aggregates01::maxNum@74 + IL_0348: stloc.s maxNum + IL_034a: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_034f: stloc.s V_41 + IL_0351: ldloc.s V_41 + IL_0353: ldnull + IL_0354: ldnull + IL_0355: ldnull + IL_0356: ldc.i4.0 + IL_0357: ldnull + IL_0358: newobj instance void Linq101Aggregates01/longestLength@77::.ctor(string, string, class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, string) - IL_03c7: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_03cc: newobj instance void Linq101Aggregates01/'longestLength@77-1'::.ctor() - IL_03d1: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MaxBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_035d: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0362: newobj instance void Linq101Aggregates01/'longestLength@77-1'::.ctor() + IL_0367: callvirt instance !!2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::MaxBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_03d6: dup - IL_03d7: stsfld int32 ''.$Linq101Aggregates01::longestLength@77 - IL_03dc: stloc.s longestLength + IL_036c: dup + IL_036d: stsfld int32 ''.$Linq101Aggregates01::longestLength@77 + IL_0372: stloc.s longestLength .line 80,86 : 1,21 '' - IL_03de: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_03e3: stloc.s V_48 - IL_03e5: ldloc.s V_48 - IL_03e7: ldloc.s V_48 - IL_03e9: ldloc.s V_48 - IL_03eb: ldloc.s V_48 - IL_03ed: ldloc.s V_48 - IL_03ef: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() - IL_03f4: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 - IL_03f9: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_03fe: ldloc.s V_48 - IL_0400: newobj instance void Linq101Aggregates01/categories4@82::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0405: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0374: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_0379: stloc.s V_42 + IL_037b: ldloc.s V_42 + IL_037d: ldloc.s V_42 + IL_037f: ldloc.s V_42 + IL_0381: ldloc.s V_42 + IL_0383: ldloc.s V_42 + IL_0385: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() + IL_038a: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 + IL_038f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0394: ldloc.s V_42 + IL_0396: newobj instance void Linq101Aggregates01/categories4@82::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_039b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_040a: newobj instance void Linq101Aggregates01/'categories4@83-1'::.ctor() - IL_040f: newobj instance void Linq101Aggregates01/'categories4@83-2'::.ctor() - IL_0414: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_03a0: newobj instance void Linq101Aggregates01/'categories4@83-1'::.ctor() + IL_03a5: newobj instance void Linq101Aggregates01/'categories4@83-2'::.ctor() + IL_03aa: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0419: ldloc.s V_48 - IL_041b: newobj instance void Linq101Aggregates01/'categories4@83-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0420: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_03af: ldloc.s V_42 + IL_03b1: newobj instance void Linq101Aggregates01/'categories4@83-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_03b6: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0425: newobj instance void Linq101Aggregates01/'categories4@85-4'::.ctor() - IL_042a: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_03bb: newobj instance void Linq101Aggregates01/'categories4@85-4'::.ctor() + IL_03c0: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_042f: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_0434: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0439: dup - IL_043a: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories4@80 - IL_043f: stloc.s categories4 + IL_03c5: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_03ca: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_03cf: dup + IL_03d0: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories4@80 + IL_03d5: stloc.s categories4 .line 89,96 : 1,21 '' - IL_0441: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0446: stloc.s V_49 - IL_0448: ldloc.s V_49 - IL_044a: ldloc.s V_49 - IL_044c: ldloc.s V_49 - IL_044e: ldloc.s V_49 - IL_0450: ldloc.s V_49 - IL_0452: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() - IL_0457: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 - IL_045c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0461: ldloc.s V_49 - IL_0463: newobj instance void Linq101Aggregates01/categories5@91::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0468: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_03d7: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_03dc: stloc.s V_43 + IL_03de: ldloc.s V_43 + IL_03e0: ldloc.s V_43 + IL_03e2: ldloc.s V_43 + IL_03e4: ldloc.s V_43 + IL_03e6: ldloc.s V_43 + IL_03e8: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() + IL_03ed: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 + IL_03f2: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_03f7: ldloc.s V_43 + IL_03f9: newobj instance void Linq101Aggregates01/categories5@91::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_03fe: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_046d: newobj instance void Linq101Aggregates01/'categories5@92-1'::.ctor() - IL_0472: newobj instance void Linq101Aggregates01/'categories5@92-2'::.ctor() - IL_0477: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0403: newobj instance void Linq101Aggregates01/'categories5@92-1'::.ctor() + IL_0408: newobj instance void Linq101Aggregates01/'categories5@92-2'::.ctor() + IL_040d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_047c: ldloc.s V_49 - IL_047e: newobj instance void Linq101Aggregates01/'categories5@92-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0483: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0412: ldloc.s V_43 + IL_0414: newobj instance void Linq101Aggregates01/'categories5@92-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0419: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`3,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0488: newobj instance void Linq101Aggregates01/'categories5@95-4'::.ctor() - IL_048d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_041e: newobj instance void Linq101Aggregates01/'categories5@95-4'::.ctor() + IL_0423: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal,class [mscorlib]System.Collections.Generic.IEnumerable`1>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0492: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_0497: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_049c: dup - IL_049d: stsfld class [mscorlib]System.Tuple`2>[] ''.$Linq101Aggregates01::categories5@89 - IL_04a2: stloc.s categories5 + IL_0428: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2>,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_042d: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0432: dup + IL_0433: stsfld class [mscorlib]System.Tuple`2>[] ''.$Linq101Aggregates01::categories5@89 + IL_0438: stloc.s categories5 .line 99,99 : 1,66 '' - IL_04a4: ldc.r8 5. - IL_04ad: ldc.r8 4. - IL_04b6: ldc.r8 1. - IL_04bf: ldc.r8 3. - IL_04c8: ldc.r8 9. - IL_04d1: ldc.r8 8. - IL_04da: ldc.r8 6. - IL_04e3: ldc.r8 7. - IL_04ec: ldc.r8 2. - IL_04f5: ldc.r8 0.0 - IL_04fe: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() - IL_0503: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_043a: ldc.r8 5. + IL_0443: ldc.r8 4. + IL_044c: ldc.r8 1. + IL_0455: ldc.r8 3. + IL_045e: ldc.r8 9. + IL_0467: ldc.r8 8. + IL_0470: ldc.r8 6. + IL_0479: ldc.r8 7. + IL_0482: ldc.r8 2. + IL_048b: ldc.r8 0.0 + IL_0494: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty() + IL_0499: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0508: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_049e: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_050d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04a3: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0512: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04a8: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0517: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04ad: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_051c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04b2: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0521: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04b7: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0526: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04bc: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_052b: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04c1: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0530: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, + IL_04c6: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1) - IL_0535: dup - IL_0536: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Aggregates01::numbers2@99 - IL_053b: stloc.s numbers2 - IL_053d: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_0542: stloc.s V_50 - IL_0544: ldloc.s V_50 - IL_0546: stloc.s V_51 - IL_0548: ldc.r8 0.0 - IL_0551: ldc.r8 0.0 - IL_055a: ldnull - IL_055b: ldc.i4.0 - IL_055c: ldc.r8 0.0 - IL_0565: newobj instance void Linq101Aggregates01/averageNum@100::.ctor(float64, + IL_04cb: dup + IL_04cc: stsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 ''.$Linq101Aggregates01::numbers2@99 + IL_04d1: stloc.s numbers2 + IL_04d3: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_04d8: stloc.s V_44 + IL_04da: ldloc.s V_44 + IL_04dc: stloc.s V_45 + IL_04de: ldc.r8 0.0 + IL_04e7: ldc.r8 0.0 + IL_04f0: ldnull + IL_04f1: ldc.i4.0 + IL_04f2: ldc.r8 0.0 + IL_04fb: newobj instance void Linq101Aggregates01/averageNum@100::.ctor(float64, float64, class [mscorlib]System.Collections.Generic.IEnumerator`1, int32, float64) - IL_056a: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_056f: newobj instance void Linq101Aggregates01/'averageNum@100-1'::.ctor() - IL_0574: newobj instance void class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor(!0, + IL_0500: newobj instance void class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_0505: newobj instance void Linq101Aggregates01/'averageNum@100-1'::.ctor() + IL_050a: newobj instance void class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor(!0, !1) - IL_0579: stloc.s V_52 - IL_057b: ldloc.s V_52 - IL_057d: call instance !0 class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::get_Item1() - IL_0582: stloc.s V_53 - IL_0584: ldloc.s V_52 - IL_0586: call instance !1 class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::get_Item2() - IL_058b: stloc.s V_54 - IL_058d: ldloc.s V_53 - IL_058f: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() - IL_0594: stloc.s V_55 - IL_0596: ldloc.s V_55 - IL_0598: box class [mscorlib]System.Collections.Generic.IEnumerable`1 - IL_059d: brfalse.s IL_05a1 - - IL_059f: br.s IL_05b4 + IL_050f: stloc.s V_46 + IL_0511: ldloc.s V_46 + IL_0513: call instance !0 class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::get_Item1() + IL_0518: stloc.s V_47 + IL_051a: ldloc.s V_46 + IL_051c: call instance !1 class [mscorlib]System.Tuple`2,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::get_Item2() + IL_0521: stloc.s V_48 + IL_0523: ldloc.s V_47 + IL_0525: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2::get_Source() + IL_052a: stloc.s V_49 + IL_052c: ldloc.s V_49 + IL_052e: box class [mscorlib]System.Collections.Generic.IEnumerable`1 + IL_0533: brfalse.s IL_0537 + + IL_0535: br.s IL_054a .line 100001,100001 : 0,0 '' - IL_05a1: ldstr "source" - IL_05a6: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string) - IL_05ab: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Raise(class [mscorlib]System.Exception) - IL_05b0: pop + IL_0537: ldstr "source" + IL_053c: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string) + IL_0541: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Raise(class [mscorlib]System.Exception) + IL_0546: pop .line 100001,100001 : 0,0 '' - IL_05b1: nop - IL_05b2: br.s IL_05b5 + IL_0547: nop + IL_0548: br.s IL_054b .line 100001,100001 : 0,0 '' .line 100001,100001 : 0,0 '' - IL_05b4: nop - IL_05b5: ldloc.s V_55 - IL_05b7: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - IL_05bc: stloc.s V_56 + IL_054a: nop + IL_054b: ldloc.s V_49 + IL_054d: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() + IL_0552: stloc.s V_50 .try { - IL_05be: ldc.r8 0.0 - IL_05c7: stloc.s V_58 - IL_05c9: ldc.i4.0 - IL_05ca: stloc.s V_59 - IL_05cc: ldloc.s V_56 - IL_05ce: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_05d3: brfalse.s IL_05f1 - - IL_05d5: ldloc.s V_58 - IL_05d7: ldloc.s V_54 - IL_05d9: ldloc.s V_56 - IL_05db: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - IL_05e0: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) - IL_05e5: add - IL_05e6: stloc.s V_58 + IL_0554: ldc.r8 0.0 + IL_055d: stloc.s V_52 + IL_055f: ldc.i4.0 + IL_0560: stloc.s V_53 + IL_0562: ldloc.s V_50 + IL_0564: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_0569: brfalse.s IL_0587 + + IL_056b: ldloc.s V_52 + IL_056d: ldloc.s V_48 + IL_056f: ldloc.s V_50 + IL_0571: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() + IL_0576: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_057b: add + IL_057c: stloc.s V_52 .line 100,100 : 47,58 '' - IL_05e8: ldloc.s V_59 - IL_05ea: ldc.i4.1 - IL_05eb: add - IL_05ec: stloc.s V_59 + IL_057e: ldloc.s V_53 + IL_0580: ldc.i4.1 + IL_0581: add + IL_0582: stloc.s V_53 .line 100001,100001 : 0,0 '' - IL_05ee: nop - IL_05ef: br.s IL_05cc + IL_0584: nop + IL_0585: br.s IL_0562 - IL_05f1: ldloc.s V_59 - IL_05f3: brtrue.s IL_05f7 + IL_0587: ldloc.s V_53 + IL_0589: brtrue.s IL_058d - IL_05f5: br.s IL_05f9 + IL_058b: br.s IL_058f - IL_05f7: br.s IL_060c + IL_058d: br.s IL_05a2 .line 100001,100001 : 0,0 '' - IL_05f9: ldstr "source" - IL_05fe: newobj instance void [mscorlib]System.InvalidOperationException::.ctor(string) - IL_0603: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Raise(class [mscorlib]System.Exception) - IL_0608: pop + IL_058f: ldstr "source" + IL_0594: newobj instance void [mscorlib]System.InvalidOperationException::.ctor(string) + IL_0599: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Raise(class [mscorlib]System.Exception) + IL_059e: pop .line 100001,100001 : 0,0 '' - IL_0609: nop - IL_060a: br.s IL_060d + IL_059f: nop + IL_05a0: br.s IL_05a3 .line 100001,100001 : 0,0 '' .line 100001,100001 : 0,0 '' - IL_060c: nop - IL_060d: ldloc.s V_58 - IL_060f: stloc.s V_60 - IL_0611: ldloc.s V_59 - IL_0613: stloc.s V_61 - IL_0615: ldloc.s V_60 - IL_0617: ldloc.s V_61 - IL_0619: conv.r8 - IL_061a: div - IL_061b: stloc.s V_57 - IL_061d: leave.s IL_063d + IL_05a2: nop + IL_05a3: ldloc.s V_52 + IL_05a5: stloc.s V_54 + IL_05a7: ldloc.s V_53 + IL_05a9: stloc.s V_55 + IL_05ab: ldloc.s V_54 + IL_05ad: ldloc.s V_55 + IL_05af: conv.r8 + IL_05b0: div + IL_05b1: stloc.s V_51 + IL_05b3: leave.s IL_05d3 } // end .try finally { - IL_061f: ldloc.s V_56 - IL_0621: isinst [mscorlib]System.IDisposable - IL_0626: stloc.s V_62 - IL_0628: ldloc.s V_62 - IL_062a: brfalse.s IL_062e + IL_05b5: ldloc.s V_50 + IL_05b7: isinst [mscorlib]System.IDisposable + IL_05bc: stloc.s V_56 + IL_05be: ldloc.s V_56 + IL_05c0: brfalse.s IL_05c4 - IL_062c: br.s IL_0630 + IL_05c2: br.s IL_05c6 - IL_062e: br.s IL_063a + IL_05c4: br.s IL_05d0 .line 100001,100001 : 0,0 '' - IL_0630: ldloc.s V_62 - IL_0632: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_0637: ldnull - IL_0638: pop - IL_0639: endfinally + IL_05c6: ldloc.s V_56 + IL_05c8: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_05cd: ldnull + IL_05ce: pop + IL_05cf: endfinally .line 100001,100001 : 0,0 '' - IL_063a: ldnull - IL_063b: pop - IL_063c: endfinally + IL_05d0: ldnull + IL_05d1: pop + IL_05d2: endfinally .line 100001,100001 : 0,0 '' } // end handler - IL_063d: ldloc.s V_57 - IL_063f: dup - IL_0640: stsfld float64 ''.$Linq101Aggregates01::averageNum@100 - IL_0645: stloc.s averageNum - IL_0647: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_064c: stloc.s V_63 - IL_064e: ldloc.s V_63 - IL_0650: stloc.s V_64 - IL_0652: ldloc.s V_63 - IL_0654: ldloc.s V_63 - IL_0656: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_words() - IL_065b: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 - IL_0660: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0665: ldloc.s V_63 - IL_0667: newobj instance void Linq101Aggregates01/averageLength@105::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_066c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_05d3: ldloc.s V_51 + IL_05d5: dup + IL_05d6: stsfld float64 ''.$Linq101Aggregates01::averageNum@100 + IL_05db: stloc.s averageNum + IL_05dd: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_05e2: stloc.s V_57 + IL_05e4: ldloc.s V_57 + IL_05e6: stloc.s V_58 + IL_05e8: ldloc.s V_57 + IL_05ea: ldloc.s V_57 + IL_05ec: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_words() + IL_05f1: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 + IL_05f6: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_05fb: ldloc.s V_57 + IL_05fd: newobj instance void Linq101Aggregates01/averageLength@105::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0602: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0671: newobj instance void Linq101Aggregates01/'averageLength@107-1'::.ctor() - IL_0676: newobj instance void class [mscorlib]System.Tuple`2,class [mscorlib]System.Collections.IEnumerable>,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64>>::.ctor(!0, + IL_0607: newobj instance void Linq101Aggregates01/'averageLength@107-1'::.ctor() + IL_060c: newobj instance void class [mscorlib]System.Tuple`2,class [mscorlib]System.Collections.IEnumerable>,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64>>::.ctor(!0, !1) - IL_067b: stloc.s V_65 - IL_067d: ldloc.s V_65 - IL_067f: call instance !0 class [mscorlib]System.Tuple`2,class [mscorlib]System.Collections.IEnumerable>,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64>>::get_Item1() - IL_0684: stloc.s V_66 - IL_0686: ldloc.s V_65 - IL_0688: call instance !1 class [mscorlib]System.Tuple`2,class [mscorlib]System.Collections.IEnumerable>,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64>>::get_Item2() - IL_068d: stloc.s V_67 - IL_068f: ldloc.s V_66 - IL_0691: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_0696: stloc.s V_68 - IL_0698: ldloc.s V_68 - IL_069a: box class [mscorlib]System.Collections.Generic.IEnumerable`1> - IL_069f: brfalse.s IL_06a3 - - IL_06a1: br.s IL_06b6 + IL_0611: stloc.s V_59 + IL_0613: ldloc.s V_59 + IL_0615: call instance !0 class [mscorlib]System.Tuple`2,class [mscorlib]System.Collections.IEnumerable>,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64>>::get_Item1() + IL_061a: stloc.s V_60 + IL_061c: ldloc.s V_59 + IL_061e: call instance !1 class [mscorlib]System.Tuple`2,class [mscorlib]System.Collections.IEnumerable>,class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64>>::get_Item2() + IL_0623: stloc.s V_61 + IL_0625: ldloc.s V_60 + IL_0627: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_062c: stloc.s V_62 + IL_062e: ldloc.s V_62 + IL_0630: box class [mscorlib]System.Collections.Generic.IEnumerable`1> + IL_0635: brfalse.s IL_0639 + + IL_0637: br.s IL_064c .line 100001,100001 : 0,0 '' - IL_06a3: ldstr "source" - IL_06a8: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string) - IL_06ad: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Raise(class [mscorlib]System.Exception) - IL_06b2: pop + IL_0639: ldstr "source" + IL_063e: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string) + IL_0643: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Raise(class [mscorlib]System.Exception) + IL_0648: pop .line 100001,100001 : 0,0 '' - IL_06b3: nop - IL_06b4: br.s IL_06b7 + IL_0649: nop + IL_064a: br.s IL_064d .line 100001,100001 : 0,0 '' .line 100001,100001 : 0,0 '' - IL_06b6: nop - IL_06b7: ldloc.s V_68 - IL_06b9: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1>::GetEnumerator() - IL_06be: stloc.s V_69 + IL_064c: nop + IL_064d: ldloc.s V_62 + IL_064f: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1>::GetEnumerator() + IL_0654: stloc.s V_63 .try { - IL_06c0: ldc.r8 0.0 - IL_06c9: stloc.s V_71 - IL_06cb: ldc.i4.0 - IL_06cc: stloc.s V_72 - IL_06ce: ldloc.s V_69 - IL_06d0: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - IL_06d5: brfalse.s IL_06f3 - - IL_06d7: ldloc.s V_71 - IL_06d9: ldloc.s V_67 - IL_06db: ldloc.s V_69 - IL_06dd: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1>::get_Current() - IL_06e2: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64>::Invoke(!0) - IL_06e7: add - IL_06e8: stloc.s V_71 + IL_0656: ldc.r8 0.0 + IL_065f: stloc.s V_65 + IL_0661: ldc.i4.0 + IL_0662: stloc.s V_66 + IL_0664: ldloc.s V_63 + IL_0666: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() + IL_066b: brfalse.s IL_0689 + + IL_066d: ldloc.s V_65 + IL_066f: ldloc.s V_61 + IL_0671: ldloc.s V_63 + IL_0673: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1>::get_Current() + IL_0678: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,float64>::Invoke(!0) + IL_067d: add + IL_067e: stloc.s V_65 .line 107,107 : 9,21 '' - IL_06ea: ldloc.s V_72 - IL_06ec: ldc.i4.1 - IL_06ed: add - IL_06ee: stloc.s V_72 + IL_0680: ldloc.s V_66 + IL_0682: ldc.i4.1 + IL_0683: add + IL_0684: stloc.s V_66 .line 100001,100001 : 0,0 '' - IL_06f0: nop - IL_06f1: br.s IL_06ce + IL_0686: nop + IL_0687: br.s IL_0664 - IL_06f3: ldloc.s V_72 - IL_06f5: brtrue.s IL_06f9 + IL_0689: ldloc.s V_66 + IL_068b: brtrue.s IL_068f - IL_06f7: br.s IL_06fb + IL_068d: br.s IL_0691 - IL_06f9: br.s IL_070e + IL_068f: br.s IL_06a4 .line 100001,100001 : 0,0 '' - IL_06fb: ldstr "source" - IL_0700: newobj instance void [mscorlib]System.InvalidOperationException::.ctor(string) - IL_0705: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Raise(class [mscorlib]System.Exception) - IL_070a: pop + IL_0691: ldstr "source" + IL_0696: newobj instance void [mscorlib]System.InvalidOperationException::.ctor(string) + IL_069b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::Raise(class [mscorlib]System.Exception) + IL_06a0: pop .line 100001,100001 : 0,0 '' - IL_070b: nop - IL_070c: br.s IL_070f + IL_06a1: nop + IL_06a2: br.s IL_06a5 .line 100001,100001 : 0,0 '' .line 100001,100001 : 0,0 '' - IL_070e: nop - IL_070f: ldloc.s V_71 - IL_0711: stloc.s V_73 - IL_0713: ldloc.s V_72 - IL_0715: stloc.s V_74 - IL_0717: ldloc.s V_73 - IL_0719: ldloc.s V_74 - IL_071b: conv.r8 - IL_071c: div - IL_071d: stloc.s V_70 - IL_071f: leave.s IL_073f + IL_06a4: nop + IL_06a5: ldloc.s V_65 + IL_06a7: stloc.s V_67 + IL_06a9: ldloc.s V_66 + IL_06ab: stloc.s V_68 + IL_06ad: ldloc.s V_67 + IL_06af: ldloc.s V_68 + IL_06b1: conv.r8 + IL_06b2: div + IL_06b3: stloc.s V_64 + IL_06b5: leave.s IL_06d5 } // end .try finally { - IL_0721: ldloc.s V_69 - IL_0723: isinst [mscorlib]System.IDisposable - IL_0728: stloc.s V_75 - IL_072a: ldloc.s V_75 - IL_072c: brfalse.s IL_0730 + IL_06b7: ldloc.s V_63 + IL_06b9: isinst [mscorlib]System.IDisposable + IL_06be: stloc.s V_69 + IL_06c0: ldloc.s V_69 + IL_06c2: brfalse.s IL_06c6 - IL_072e: br.s IL_0732 + IL_06c4: br.s IL_06c8 - IL_0730: br.s IL_073c + IL_06c6: br.s IL_06d2 .line 100001,100001 : 0,0 '' - IL_0732: ldloc.s V_75 - IL_0734: callvirt instance void [mscorlib]System.IDisposable::Dispose() - IL_0739: ldnull - IL_073a: pop - IL_073b: endfinally + IL_06c8: ldloc.s V_69 + IL_06ca: callvirt instance void [mscorlib]System.IDisposable::Dispose() + IL_06cf: ldnull + IL_06d0: pop + IL_06d1: endfinally .line 100001,100001 : 0,0 '' - IL_073c: ldnull - IL_073d: pop - IL_073e: endfinally + IL_06d2: ldnull + IL_06d3: pop + IL_06d4: endfinally .line 100001,100001 : 0,0 '' } // end handler - IL_073f: ldloc.s V_70 - IL_0741: dup - IL_0742: stsfld float64 ''.$Linq101Aggregates01::averageLength@103 - IL_0747: stloc.s averageLength + IL_06d5: ldloc.s V_64 + IL_06d7: dup + IL_06d8: stsfld float64 ''.$Linq101Aggregates01::averageLength@103 + IL_06dd: stloc.s averageLength .line 111,117 : 1,21 '' - IL_0749: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() - IL_074e: stloc.s V_76 - IL_0750: ldloc.s V_76 - IL_0752: ldloc.s V_76 - IL_0754: ldloc.s V_76 - IL_0756: ldloc.s V_76 - IL_0758: ldloc.s V_76 - IL_075a: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() - IL_075f: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 - IL_0764: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_0769: ldloc.s V_76 - IL_076b: newobj instance void Linq101Aggregates01/categories6@113::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_0770: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_06df: call class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_query() + IL_06e4: stloc.s V_70 + IL_06e6: ldloc.s V_70 + IL_06e8: ldloc.s V_70 + IL_06ea: ldloc.s V_70 + IL_06ec: ldloc.s V_70 + IL_06ee: ldloc.s V_70 + IL_06f0: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 Linq101Aggregates01::get_products() + IL_06f5: unbox.any class [mscorlib]System.Collections.Generic.IEnumerable`1 + IL_06fa: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Source(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_06ff: ldloc.s V_70 + IL_0701: newobj instance void Linq101Aggregates01/categories6@113::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0706: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0775: newobj instance void Linq101Aggregates01/'categories6@114-1'::.ctor() - IL_077a: newobj instance void Linq101Aggregates01/'categories6@114-2'::.ctor() - IL_077f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_070b: newobj instance void Linq101Aggregates01/'categories6@114-1'::.ctor() + IL_0710: newobj instance void Linq101Aggregates01/'categories6@114-2'::.ctor() + IL_0715: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,!!3> [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::GroupValBy(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0784: ldloc.s V_76 - IL_0786: newobj instance void Linq101Aggregates01/'categories6@114-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) - IL_078b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_071a: ldloc.s V_70 + IL_071c: newobj instance void Linq101Aggregates01/'categories6@114-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder) + IL_0721: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::For,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2,valuetype [mscorlib]System.Decimal>,object>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0790: newobj instance void Linq101Aggregates01/'categories6@116-4'::.ctor() - IL_0795: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, + IL_0726: newobj instance void Linq101Aggregates01/'categories6@116-4'::.ctor() + IL_072b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2 [FSharp.Core]Microsoft.FSharp.Linq.QueryBuilder::Select,valuetype [mscorlib]System.Decimal>,class [mscorlib]System.Collections.IEnumerable,class [mscorlib]System.Tuple`2>(class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_079a: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() - IL_079f: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) - IL_07a4: dup - IL_07a5: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories6@111 - IL_07aa: stloc.s categories6 - IL_07ac: ret + IL_0730: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerable`1 class [FSharp.Core]Microsoft.FSharp.Linq.QuerySource`2,class [mscorlib]System.Collections.IEnumerable>::get_Source() + IL_0735: call !!0[] [FSharp.Core]Microsoft.FSharp.Collections.SeqModule::ToArray>(class [mscorlib]System.Collections.Generic.IEnumerable`1) + IL_073a: dup + IL_073b: stsfld class [mscorlib]System.Tuple`2[] ''.$Linq101Aggregates01::categories6@111 + IL_0740: stloc.s categories6 + IL_0742: ret } // end of method $Linq101Aggregates01::main@ } // end of class ''.$Linq101Aggregates01 diff --git a/tests/fsharpqa/Source/Misc/LongSourceFile01.fs b/tests/fsharpqa/Source/Misc/LongSourceFile01.fs index 970a5f77ff6..ce49bd6d74d 100644 --- a/tests/fsharpqa/Source/Misc/LongSourceFile01.fs +++ b/tests/fsharpqa/Source/Misc/LongSourceFile01.fs @@ -163,6 +163,63 @@ Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.ICom Microsoft.FSharp.Collections.ComparisonIdentity: System.Collections.Generic.IComparer`1[T] Structural[T]() Microsoft.FSharp.Collections.ComparisonIdentity: System.String ToString() Microsoft.FSharp.Collections.ComparisonIdentity: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void .ctor() +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult]: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: TResult Value +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void .ctor(TResult) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult]: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining: Void OnDispose() +Microsoft.FSharp.Collections.ComposerModule+Core+IOutOfBand: Void StopFurtherProcessing(Int32) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Consumer`2 Create[V](IOutOfBand, System.Nullable`1[System.Int32], Consumer`2) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Int32 PipeIdx +Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult]: Int32 get_PipeIdx() +Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T]: ISeq`1 Compose[TResult](ISeqFactory`2) +Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T]: a ForEach[a](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit],a]) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: Void .ctor(a, b) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: a _1 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b]: b _2 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: Void .ctor(a, b, c) +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: a _1 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: b _2 +Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c]: c _3 +Microsoft.FSharp.Collections.ComposerModule+Core: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule+Core: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Consumer`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Folder`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ICompletionChaining +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+IOutOfBand +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ISeqFactory`2[T,TResult] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+ISeq`1[T] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Values`2[a,b] +Microsoft.FSharp.Collections.ComposerModule+Core: Microsoft.FSharp.Collections.ComposerModule+Core+Values`3[a,b,c] +Microsoft.FSharp.Collections.ComposerModule+Core: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule+Core: System.Type GetType() +Microsoft.FSharp.Collections.ComposerModule: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ComposerModule: Int32 GetHashCode() +Microsoft.FSharp.Collections.ComposerModule: Microsoft.FSharp.Collections.ComposerModule+Core +Microsoft.FSharp.Collections.ComposerModule: System.String ToString() +Microsoft.FSharp.Collections.ComposerModule: System.Type GetType() Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Boolean Equals(System.Object) Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Cons Microsoft.FSharp.Collections.FSharpList`1+Tags[T]: Int32 Empty @@ -348,6 +405,7 @@ Microsoft.FSharp.Collections.SeqModule: Boolean Exists[T](Microsoft.FSharp.Core. Microsoft.FSharp.Collections.SeqModule: Boolean ForAll2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], System.Collections.Generic.IEnumerable`1[T1], System.Collections.Generic.IEnumerable`1[T2]) Microsoft.FSharp.Collections.SeqModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Boolean IsEmpty[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.SeqModule: ISeq`1 ToComposer[T](System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], System.Collections.Generic.IEnumerable`1[T], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Int32 GetHashCode()