diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj b/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj index f851d9ca395..ecc6aec03b6 100644 --- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj +++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core.Unittests.fsproj @@ -93,6 +93,11 @@ + + + + + diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ISeqModule.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ISeqModule.fs new file mode 100644 index 00000000000..65531fdf073 --- /dev/null +++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ISeqModule.fs @@ -0,0 +1,1166 @@ +// 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 FSharp.Core.Unittests.FSharp_Core.Microsoft_FSharp_Collections + +open System +open NUnit.Framework + +open FSharp.Core.Unittests.LibraryTestFx + +// Various tests for the: +// Microsoft.FSharp.Collections.iseq type + +(* +[Test Strategy] +Make sure each method works on: +* Integer ISeq (value type) +* String ISeq (reference type) +* Empty ISeq (0 elements) +* Null ISeq (null) +*) + +type iseq<'a> = FSharp.Collections.SeqComposition.ISeq<'a> + +[] +type ISeqModule() = + let iseq (x:seq<_>) = x |> ISeq.ofSeq + + [] + member this.AllPairs() = + + // integer ISeq + let resultInt = ISeq.allPairs (iseq [1..7]) (iseq [11..17]) + let expectedInt = + iseq <| seq { for i in 1..7 do + for j in 11..17 do + yield i, j } + VerifySeqsEqual expectedInt resultInt + + // string ISeq + let resultStr = ISeq.allPairs (iseq ["str3";"str4"]) (iseq ["str1";"str2"]) + let expectedStr = iseq ["str3","str1";"str3","str2";"str4","str1";"str4","str2"] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + VerifySeqsEqual ISeq.empty <| ISeq.allPairs ISeq.empty ISeq.empty + VerifySeqsEqual ISeq.empty <| ISeq.allPairs (iseq { 1..7 }) ISeq.empty + VerifySeqsEqual ISeq.empty <| ISeq.allPairs ISeq.empty (iseq { 1..7 }) + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.allPairs null null |> ignore) + //CheckThrowsArgumentNullException(fun() -> ISeq.allPairs null (iseq [1..7]) |> ignore) + //CheckThrowsArgumentNullException(fun() -> ISeq.allPairs (iseq [1..7]) null |> ignore) + () + + [] + member this.CachedSeq_Clear() = + + let evaluatedItems : int list ref = ref [] + let cachedSeq = + ISeq.initInfinite (fun i -> evaluatedItems := i :: !evaluatedItems; i) + |> ISeq.cache + + // Verify no items have been evaluated from the ISeq yet + Assert.AreEqual(List.length !evaluatedItems, 0) + + // Force evaluation of 10 elements + ISeq.take 10 cachedSeq + |> ISeq.toList + |> ignore + + // verify ref clear switch length + Assert.AreEqual(List.length !evaluatedItems, 10) + + // Force evaluation of 10 elements + ISeq.take 10 cachedSeq + |> ISeq.toList + |> ignore + + // Verify ref clear switch length (should be cached) + Assert.AreEqual(List.length !evaluatedItems, 10) + + + // Clear + (box cachedSeq :?> System.IDisposable) .Dispose() + + // Force evaluation of 10 elements + ISeq.take 10 cachedSeq + |> ISeq.toList + |> ignore + + // Verify length of evaluatedItemList is 20 + Assert.AreEqual(List.length !evaluatedItems, 20) + () + + [] + member this.Append() = + + // empty ISeq + let emptySeq1 = ISeq.empty + let emptySeq2 = ISeq.empty + let appendEmptySeq = ISeq.append emptySeq1 emptySeq2 + let expectResultEmpty = ISeq.empty + + VerifySeqsEqual expectResultEmpty appendEmptySeq + + // Integer ISeq + let integerSeq1:iseq = iseq [0..4] + let integerSeq2:iseq = iseq [5..9] + + let appendIntergerSeq = ISeq.append integerSeq1 integerSeq2 + + let expectResultInteger = iseq <| seq { for i in 0..9 -> i} + + VerifySeqsEqual expectResultInteger appendIntergerSeq + + + // String ISeq + let stringSeq1:iseq = iseq ["1";"2"] + let stringSeq2:iseq = iseq ["3";"4"] + + let appendStringSeq = ISeq.append stringSeq1 stringSeq2 + + let expectedResultString = iseq ["1";"2";"3";"4"] + + VerifySeqsEqual expectedResultString appendStringSeq + + // null ISeq + let nullSeq1 = iseq [null;null] + + let nullSeq2 =iseq [null;null] + + let appendNullSeq = ISeq.append nullSeq1 nullSeq2 + + let expectedResultNull = iseq [ null;null;null;null] + + VerifySeqsEqual expectedResultNull appendNullSeq + + () + + [] + member this.replicate() = + // replicate should create multiple copies of the given value + Assert.IsTrue(ISeq.isEmpty <| ISeq.replicate 0 null) + Assert.IsTrue(ISeq.isEmpty <| ISeq.replicate 0 1) + Assert.AreEqual(null, ISeq.head <| ISeq.replicate 1 null) + Assert.AreEqual(["1";"1"],ISeq.replicate 2 "1" |> ISeq.toList) + + CheckThrowsArgumentException (fun () -> ISeq.replicate -1 null |> ignore) + + + [] + member this.Average() = + // empty ISeq + let emptySeq:iseq = ISeq.empty + + CheckThrowsArgumentException (fun () -> ISeq.average emptySeq |> ignore) + + + // double ISeq + let doubleSeq:iseq = iseq [1.0;2.2;2.5;4.3] + + let averageDouble = ISeq.average doubleSeq + + Assert.IsFalse( averageDouble <> 2.5) + + // float32 ISeq + let floatSeq:iseq = iseq [ 2.0f;4.4f;5.0f;8.6f] + + let averageFloat = ISeq.average floatSeq + + Assert.IsFalse( averageFloat <> 5.0f) + + // decimal ISeq + let decimalSeq:iseq = iseq [ 0M;19M;19.03M] + + let averageDecimal = ISeq.average decimalSeq + + Assert.IsFalse( averageDecimal <> 12.676666666666666666666666667M ) + + //// null ISeq + //let nullSeq:iseq = null + + //CheckThrowsArgumentNullException (fun () -> ISeq.average nullSeq |> ignore) + () + + + [] + member this.AverageBy() = + // empty ISeq + let emptySeq:iseq = ISeq.empty + + CheckThrowsArgumentException (fun () -> ISeq.averageBy (fun x -> x+1.0) emptySeq |> ignore) + + // double ISeq + let doubleSeq:iseq = iseq [1.0;2.2;2.5;4.3] + + let averageDouble = ISeq.averageBy (fun x -> x-2.0) doubleSeq + + Assert.IsFalse( averageDouble <> 0.5 ) + + // float32 ISeq + let floatSeq:iseq = iseq [ 2.0f;4.4f;5.0f;8.6f] + + let averageFloat = ISeq.averageBy (fun x -> x*3.3f) floatSeq + + Assert.IsFalse( averageFloat <> 16.5f ) + + // decimal ISeq + let decimalSeq:iseq = iseq [ 0M;19M;19.03M] + + let averageDecimal = ISeq.averageBy (fun x -> x/10.7M) decimalSeq + + Assert.IsFalse( averageDecimal <> 1.1847352024922118380062305296M ) + + //// null ISeq + //let nullSeq:iseq = null + + //CheckThrowsArgumentNullException (fun () -> ISeq.averageBy (fun (x:double)->x+4.0) nullSeq |> ignore) + () + + [] + member this.Cache() = + // empty ISeq + let emptySeq:iseq = ISeq.empty + + let cacheEmpty = ISeq.cache emptySeq + + let expectedResultEmpty = ISeq.empty + + VerifySeqsEqual expectedResultEmpty cacheEmpty + + // double ISeq + let doubleSeq:iseq = iseq [1.0;2.2;2.5;4.3] + + let cacheDouble = ISeq.cache doubleSeq + + VerifySeqsEqual doubleSeq cacheDouble + + + // float32 ISeq + let floatSeq:iseq = iseq [ 2.0f;4.4f;5.0f;8.6f] + + let cacheFloat = ISeq.cache floatSeq + + VerifySeqsEqual floatSeq cacheFloat + + // decimal ISeq + let decimalSeq:iseq = iseq [ 0M; 19M; 19.03M] + + let cacheDecimal = ISeq.cache decimalSeq + + VerifySeqsEqual decimalSeq cacheDecimal + + // null ISeq + let nullSeq = iseq [null] + + let cacheNull = ISeq.cache nullSeq + + VerifySeqsEqual nullSeq cacheNull + () + + [] + member this.Case() = + + // integer ISeq + let integerArray = [|1;2|] + let integerSeq = ISeq.cast integerArray + + let expectedIntegerSeq = iseq [1;2] + + VerifySeqsEqual expectedIntegerSeq integerSeq + + // string ISeq + let stringArray = [|"a";"b"|] + let stringSeq = ISeq.cast stringArray + + let expectedStringSeq = iseq["a";"b"] + + VerifySeqsEqual expectedStringSeq stringSeq + + // empty ISeq + let emptySeq = ISeq.cast ISeq.empty + let expectedEmptySeq = ISeq.empty + + VerifySeqsEqual expectedEmptySeq ISeq.empty + + // null ISeq + let nullArray = [|null;null|] + let NullSeq = ISeq.cast nullArray + let expectedNullSeq = iseq [null;null] + + VerifySeqsEqual expectedNullSeq NullSeq + + CheckThrowsExn(fun () -> + let strings = + integerArray + |> ISeq.cast + for o in strings do ()) + + CheckThrowsExn(fun () -> + let strings = + integerArray + |> ISeq.cast + :> System.Collections.IEnumerable // without this upcast the for loop throws, so it should with this upcast too + for o in strings do ()) + + () + + [] + member this.Choose() = + + // int ISeq + let intSeq = iseq [1..20] + let funcInt x = if (x%5=0) then Some x else None + let intChoosed = ISeq.choose funcInt intSeq + let expectedIntChoosed = iseq <| seq { for i = 1 to 4 do yield i*5} + + + + VerifySeqsEqual expectedIntChoosed intChoosed + + // string ISeq + let stringSrc = iseq ["list";"List"] + let funcString x = match x with + | "list"-> Some x + | "List" -> Some x + | _ -> None + let strChoosed = ISeq.choose funcString stringSrc + let expectedStrChoose = iseq ["list";"List"] + + VerifySeqsEqual expectedStrChoose strChoosed + + // empty ISeq + let emptySeq = ISeq.empty + let emptyChoosed = ISeq.choose funcInt emptySeq + + let expectedEmptyChoose = ISeq.empty + + VerifySeqsEqual expectedEmptyChoose emptySeq + + + //// null ISeq + //let nullSeq:iseq<'a> = null + + //CheckThrowsArgumentNullException (fun () -> ISeq.choose funcInt nullSeq |> ignore) + () + + [] + member this.ChunkBySize() = + + let verify expected actual = + ISeq.zip expected actual + |> ISeq.iter ((<||) VerifySeqsEqual) + + // int ISeq + verify (iseq [[1..4];[5..8]]) <| ISeq.chunkBySize 4 (iseq {1..8}) + verify (iseq [[1..4];[5..8];[9..10]]) <| ISeq.chunkBySize 4 (iseq {1..10}) + verify (iseq [[1]; [2]; [3]; [4]]) <| ISeq.chunkBySize 1 (iseq {1..4}) + + ISeq.chunkBySize 2 (ISeq.initInfinite id) + |> ISeq.take 3 + |> verify (iseq [[0;1];[2;3];[4;5]]) + + ISeq.chunkBySize 1 (ISeq.initInfinite id) + |> ISeq.take 5 + |> verify (iseq [[0];[1];[2];[3];[4]]) + + // string ISeq + verify (iseq [["a"; "b"];["c";"d"];["e"]]) <| ISeq.chunkBySize 2 (iseq ["a";"b";"c";"d";"e"]) + + // empty ISeq + verify ISeq.empty <| ISeq.chunkBySize 3 ISeq.empty + + //// null ISeq + //let nullSeq:iseq<_> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.chunkBySize 3 nullSeq |> ignore) + + // invalidArg + CheckThrowsArgumentException (fun () -> ISeq.chunkBySize 0 (iseq {1..10}) |> ignore) + CheckThrowsArgumentException (fun () -> ISeq.chunkBySize -1 (iseq {1..10}) |> ignore) + + () + + [] + member this.SplitInto() = + + let verify expected actual = + ISeq.zip expected actual + |> ISeq.iter ((<||) VerifySeqsEqual) + + // int ISeq + ISeq.splitInto 3 (iseq {1..10}) |> verify (iseq [ {1..4}; {5..7}; {8..10} ]) + ISeq.splitInto 3 (iseq {1..11}) |> verify (iseq [ {1..4}; {5..8}; {9..11} ]) + ISeq.splitInto 3 (iseq {1..12}) |> verify (iseq [ {1..4}; {5..8}; {9..12} ]) + + ISeq.splitInto 4 (iseq {1..5}) |> verify (iseq [ [1..2]; [3]; [4]; [5] ]) + ISeq.splitInto 20 (iseq {1..4}) |> verify (iseq [ [1]; [2]; [3]; [4] ]) + + // string ISeq + ISeq.splitInto 3 (iseq ["a";"b";"c";"d";"e"]) |> verify (iseq [ ["a"; "b"]; ["c";"d"]; ["e"] ]) + + // empty ISeq + VerifySeqsEqual [] <| ISeq.splitInto 3 (iseq []) + + //// null ISeq + //let nullSeq:iseq<_> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.splitInto 3 nullSeq |> ignore) + + // invalidArg + CheckThrowsArgumentException (fun () -> ISeq.splitInto 0 (iseq [1..10]) |> ignore) + CheckThrowsArgumentException (fun () -> ISeq.splitInto -1 (iseq [1..10]) |> ignore) + + () + + [] + member this.Compare() = + + // int ISeq + let intSeq1 = iseq [1;3;7;9] + let intSeq2 = iseq [2;4;6;8] + let funcInt x y = if (x>y) then x else 0 + let intcompared = ISeq.compareWith funcInt intSeq1 intSeq2 + + Assert.IsFalse( intcompared <> 7 ) + + // string ISeq + let stringSeq1 = iseq ["a"; "b"] + let stringSeq2 = iseq ["c"; "d"] + let funcString x y = match (x,y) with + | "a", "c" -> 0 + | "b", "d" -> 1 + |_ -> -1 + let strcompared = ISeq.compareWith funcString stringSeq1 stringSeq2 + Assert.IsFalse( strcompared <> 1 ) + + // empty ISeq + let emptySeq = ISeq.empty + let emptycompared = ISeq.compareWith funcInt emptySeq emptySeq + + Assert.IsFalse( emptycompared <> 0 ) + + //// null ISeq + //let nullSeq:iseq = null + + //CheckThrowsArgumentNullException (fun () -> ISeq.compareWith funcInt nullSeq emptySeq |> ignore) + //CheckThrowsArgumentNullException (fun () -> ISeq.compareWith funcInt emptySeq nullSeq |> ignore) + //CheckThrowsArgumentNullException (fun () -> ISeq.compareWith funcInt nullSeq nullSeq |> ignore) + + () + + [] + member this.Concat() = + // integer ISeq + let seqInt = + iseq <| seq { for i in 0..9 do + yield iseq <| seq {for j in 0..9 do + yield i*10+j}} + let conIntSeq = ISeq.concat seqInt + let expectedIntSeq = iseq <| seq { for i in 0..99 do yield i} + + VerifySeqsEqual expectedIntSeq conIntSeq + + // string ISeq + let strSeq = + iseq <| seq { for a in 'a' .. 'b' do + for b in 'a' .. 'b' do + yield iseq [a; b] } + + let conStrSeq = ISeq.concat strSeq + let expectedStrSeq = iseq ['a';'a';'a';'b';'b';'a';'b';'b';] + VerifySeqsEqual expectedStrSeq conStrSeq + + // Empty ISeq + let emptySeqs = iseq [iseq[ ISeq.empty;ISeq.empty];iseq[ ISeq.empty;ISeq.empty]] + let conEmptySeq = ISeq.concat emptySeqs + let expectedEmptySeq =iseq <| seq { for i in 1..4 do yield ISeq.empty} + + VerifySeqsEqual expectedEmptySeq conEmptySeq + + //// null ISeq + //let nullSeq:iseq<'a> = null + + //CheckThrowsArgumentNullException (fun () -> ISeq.concat nullSeq |> ignore) + + () + + [] + member this.CountBy() = + // integer ISeq + let funcIntCount_by (x:int) = x%3 + let seqInt = + iseq <| seq { for i in 0..9 do + yield i} + let countIntSeq = ISeq.countByVal funcIntCount_by seqInt + + let expectedIntSeq = iseq [0,4;1,3;2,3] + + VerifySeqsEqual expectedIntSeq countIntSeq + + // string ISeq + let funcStrCount_by (s:string) = s.IndexOf("key") + let strSeq = iseq [ "key";"blank key";"key";"blank blank key"] + + let countStrSeq = ISeq.countByVal funcStrCount_by strSeq + let expectedStrSeq = iseq [0,2;6,1;12,1] + VerifySeqsEqual expectedStrSeq countStrSeq + + // Empty ISeq + let emptySeq = ISeq.empty + let countEmptySeq = ISeq.countByVal funcIntCount_by emptySeq + let expectedEmptySeq =iseq [] + + VerifySeqsEqual expectedEmptySeq countEmptySeq + + //// null ISeq + //let nullSeq:iseq<'a> = null + + //CheckThrowsArgumentNullException (fun () -> ISeq.countBy funcIntCount_by nullSeq |> ignore) + () + + [] + member this.Distinct() = + + // integer ISeq + let IntDistinctSeq = + iseq <| seq { for i in 0..9 do + yield i % 3 } + + let DistinctIntSeq = ISeq.distinct IntDistinctSeq + + let expectedIntSeq = iseq [0;1;2] + + VerifySeqsEqual expectedIntSeq DistinctIntSeq + + // string ISeq + let strDistinctSeq = iseq ["elementDup"; "ele1"; "ele2"; "elementDup"] + + let DistnctStrSeq = ISeq.distinct strDistinctSeq + let expectedStrSeq = iseq ["elementDup"; "ele1"; "ele2"] + VerifySeqsEqual expectedStrSeq DistnctStrSeq + + // Empty ISeq + let emptySeq : iseq = ISeq.empty + let distinctEmptySeq : iseq = ISeq.distinct emptySeq + let expectedEmptySeq : iseq = iseq [] + + VerifySeqsEqual expectedEmptySeq distinctEmptySeq + + //// null ISeq + //let nullSeq:iseq = null + + //CheckThrowsArgumentNullException(fun () -> ISeq.distinct nullSeq |> ignore) + () + + [] + member this.DistinctBy () = + // integer ISeq + let funcInt x = x % 3 + let IntDistinct_bySeq = + iseq <| seq { for i in 0..9 do + yield i } + + let distinct_byIntSeq = ISeq.distinctBy funcInt IntDistinct_bySeq + + let expectedIntSeq = iseq [0;1;2] + + VerifySeqsEqual expectedIntSeq distinct_byIntSeq + + // string ISeq + let funcStrDistinct (s:string) = s.IndexOf("key") + let strSeq = iseq [ "key"; "blank key"; "key dup"; "blank key dup"] + + let DistnctStrSeq = ISeq.distinctBy funcStrDistinct strSeq + let expectedStrSeq = iseq ["key"; "blank key"] + VerifySeqsEqual expectedStrSeq DistnctStrSeq + + // Empty ISeq + let emptySeq : iseq = ISeq.empty + let distinct_byEmptySeq : iseq = ISeq.distinctBy funcInt emptySeq + let expectedEmptySeq : iseq = iseq [] + + VerifySeqsEqual expectedEmptySeq distinct_byEmptySeq + + //// null ISeq + //let nullSeq : iseq<'a> = null + + //CheckThrowsArgumentNullException(fun () -> ISeq.distinctBy funcInt nullSeq |> ignore) + () + + [] + member this.Except() = + // integer ISeq + let intSeq1 = iseq <| seq { yield! {1..100} + yield! {1..100} } + let intSeq2 = {1..10} + let expectedIntSeq = {11..100} + + VerifySeqsEqual expectedIntSeq <| ISeq.except intSeq2 intSeq1 + + // string ISeq + let strSeq1 = iseq ["a"; "b"; "c"; "d"; "a"] + let strSeq2 = iseq ["b"; "c"] + let expectedStrSeq = iseq ["a"; "d"] + + VerifySeqsEqual expectedStrSeq <| ISeq.except strSeq2 strSeq1 + + // double ISeq + // Sequences with nan do not behave, due to the F# generic equality comparisons +// let floatSeq1 = iseq [1.0; 1.0; System.Double.MaxValue; nan; nan] +// +// VerifySeqsEqual [1.0; System.Double.MaxValue; nan; nan] <| ISeq.except [] floatSeq1 +// VerifySeqsEqual [1.0; System.Double.MaxValue] <| ISeq.except [nan] floatSeq1 + + // empty ISeq + let emptyIntSeq = ISeq.empty + VerifySeqsEqual {1..100} <| ISeq.except emptyIntSeq intSeq1 + VerifySeqsEqual emptyIntSeq <| ISeq.except intSeq1 emptyIntSeq + VerifySeqsEqual emptyIntSeq <| ISeq.except emptyIntSeq emptyIntSeq + VerifySeqsEqual emptyIntSeq <| ISeq.except intSeq1 intSeq1 + + //// null ISeq + //let nullSeq : iseq = null + //CheckThrowsArgumentNullException(fun () -> ISeq.except nullSeq emptyIntSeq |> ignore) + //CheckThrowsArgumentNullException(fun () -> ISeq.except emptyIntSeq nullSeq |> ignore) + //CheckThrowsArgumentNullException(fun () -> ISeq.except nullSeq nullSeq |> ignore) + + () + + [] + member this.Exists() = + + // Integer ISeq + let funcInt x = (x % 2 = 0) + let IntexistsSeq = + iseq <| seq { for i in 0..9 do + yield i} + + let ifExistInt = ISeq.exists funcInt IntexistsSeq + + Assert.IsTrue( ifExistInt) + + // String ISeq + let funcStr (s:string) = s.Contains("key") + let strSeq = iseq ["key"; "blank key"] + + let ifExistStr = ISeq.exists funcStr strSeq + + Assert.IsTrue( ifExistStr) + + // Empty ISeq + let emptySeq = ISeq.empty + let ifExistsEmpty = ISeq.exists funcInt emptySeq + + Assert.IsFalse( ifExistsEmpty) + + + + //// null ISeq + //let nullSeq:iseq<'a> = null + + //CheckThrowsArgumentNullException (fun () -> ISeq.exists funcInt nullSeq |> ignore) + () + + [] + member this.Exists2() = + // Integer ISeq + let funcInt x y = (x+y)%3=0 + let Intexists2Seq1 = iseq [1;3;7] + let Intexists2Seq2 = iseq [1;6;3] + + let ifExist2Int = ISeq.exists2 funcInt Intexists2Seq1 Intexists2Seq2 + Assert.IsTrue( ifExist2Int) + + // String ISeq + let funcStr s1 s2 = ((s1 + s2) = "CombinedString") + let strSeq1 = iseq [ "Combined"; "Not Combined"] + let strSeq2 = iseq ["String"; "Other String"] + let ifexists2Str = ISeq.exists2 funcStr strSeq1 strSeq2 + Assert.IsTrue(ifexists2Str) + + // Empty ISeq + let emptySeq = ISeq.empty + let ifexists2Empty = ISeq.exists2 funcInt emptySeq emptySeq + Assert.IsFalse( ifexists2Empty) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.exists2 funcInt nullSeq nullSeq |> ignore) + () + + + [] + member this.Filter() = + // integer ISeq + let funcInt x = if (x % 5 = 0) then true else false + let IntSeq = + iseq <| seq { for i in 1..20 do + yield i } + + let filterIntSeq = ISeq.filter funcInt IntSeq + + let expectedfilterInt = iseq [ 5;10;15;20] + + VerifySeqsEqual expectedfilterInt filterIntSeq + + // string ISeq + let funcStr (s:string) = s.Contains("Expected Content") + let strSeq = iseq [ "Expected Content"; "Not Expected"; "Expected Content"; "Not Expected"] + + let filterStrSeq = ISeq.filter funcStr strSeq + + let expectedfilterStr = iseq ["Expected Content"; "Expected Content"] + + VerifySeqsEqual expectedfilterStr filterStrSeq + // Empty ISeq + let emptySeq = ISeq.empty + let filterEmptySeq = ISeq.filter funcInt emptySeq + + let expectedEmptySeq =iseq [] + + VerifySeqsEqual expectedEmptySeq filterEmptySeq + + + + //// null ISeq + //let nullSeq:iseq<'a> = null + + //CheckThrowsArgumentNullException (fun () -> ISeq.filter funcInt nullSeq |> ignore) + () + + [] + member this.Find() = + + // integer ISeq + let funcInt x = if (x % 5 = 0) then true else false + let IntSeq = + iseq <| seq { for i in 1..20 do + yield i } + + let findInt = ISeq.find funcInt IntSeq + Assert.AreEqual(findInt, 5) + + // string ISeq + let funcStr (s:string) = s.Contains("Expected Content") + let strSeq = iseq [ "Expected Content";"Not Expected"] + + let findStr = ISeq.find funcStr strSeq + Assert.AreEqual(findStr, "Expected Content") + + // Empty ISeq + let emptySeq = ISeq.empty + + CheckThrowsKeyNotFoundException(fun () -> ISeq.find funcInt emptySeq |> ignore) + + // null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.find funcInt nullSeq |> ignore) + () + + [] + member this.FindBack() = + // integer ISeq + let funcInt x = x % 5 = 0 + Assert.AreEqual(20, ISeq.findBack funcInt <| (iseq <| seq { 1..20 })) + Assert.AreEqual(15, ISeq.findBack funcInt <| (iseq <| seq { 1..19 })) + Assert.AreEqual(5, ISeq.findBack funcInt <| (iseq <| seq { 5..9 })) + + // string ISeq + let funcStr (s:string) = s.Contains("Expected") + let strSeq = iseq [ "Not Expected"; "Expected Content"] + let findStr = ISeq.findBack funcStr strSeq + Assert.AreEqual("Expected Content", findStr) + + // Empty ISeq + let emptySeq = ISeq.empty + CheckThrowsKeyNotFoundException(fun () -> ISeq.findBack funcInt emptySeq |> ignore) + + // Not found + let emptySeq = ISeq.empty + CheckThrowsKeyNotFoundException(fun () -> iseq <| seq { 1..20 } |> ISeq.findBack (fun _ -> false) |> ignore) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.findBack funcInt nullSeq |> ignore) + () + + [] + member this.FindIndex() = + + // integer ISeq + let digits = [1 .. 100] |> ISeq.ofList + let idx = digits |> ISeq.findIndex (fun i -> i.ToString().Length > 1) + Assert.AreEqual(idx, 9) + + // empty ISeq + CheckThrowsKeyNotFoundException(fun () -> ISeq.findIndex (fun i -> true) ISeq.empty |> ignore) + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.findIndex (fun i -> true) null |> ignore) + () + + [] + member this.Permute() = + let mapIndex i = (i + 1) % 4 + + // integer iseq + let intSeq = iseq <| seq { 1..4 } + let resultInt = ISeq.permute mapIndex intSeq + VerifySeqsEqual (iseq [4;1;2;3]) resultInt + + // string iseq + let resultStr = ISeq.permute mapIndex (iseq [|"Lists"; "are"; "commonly"; "list" |]) + VerifySeqsEqual (iseq ["list"; "Lists"; "are"; "commonly" ]) resultStr + + // empty iseq + let resultEpt = ISeq.permute mapIndex (iseq [||]) + VerifySeqsEqual ISeq.empty resultEpt + + //// null iseq + //let nullSeq = null:string[] + //CheckThrowsArgumentNullException (fun () -> ISeq.permute mapIndex nullSeq |> ignore) + + // argument exceptions + CheckThrowsArgumentException (fun () -> ISeq.permute (fun _ -> 10) (iseq [0..9]) |> ISeq.iter ignore) + CheckThrowsArgumentException (fun () -> ISeq.permute (fun _ -> 0) (iseq [0..9]) |> ISeq.iter ignore) + () + + [] + member this.FindIndexBack() = + // integer ISeq + let digits = iseq <| seq { 1..100 } + let idx = digits |> ISeq.findIndexBack (fun i -> i.ToString().Length = 1) + Assert.AreEqual(idx, 8) + + // string ISeq + let funcStr (s:string) = s.Contains("Expected") + let strSeq = iseq [ "Not Expected"; "Expected Content" ] + let findStr = ISeq.findIndexBack funcStr strSeq + Assert.AreEqual(1, findStr) + + // empty ISeq + CheckThrowsKeyNotFoundException(fun () -> ISeq.findIndexBack (fun i -> true) ISeq.empty |> ignore) + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.findIndexBack (fun i -> true) null |> ignore) + () + + [] + member this.Pick() = + + let digits = [| 1 .. 10 |] |> ISeq.ofArray + let result = ISeq.pick (fun i -> if i > 5 then Some(i.ToString()) else None) digits + Assert.AreEqual(result, "6") + + // Empty iseq (Bugged, 4173) + CheckThrowsKeyNotFoundException (fun () -> ISeq.pick (fun i -> Some('a')) (iseq ([| |] : int[])) |> ignore) + + //// Null + //CheckThrowsArgumentNullException (fun () -> ISeq.pick (fun i -> Some(i + 0)) null |> ignore) + () + + [] + member this.Fold() = + let funcInt x y = x+y + + let IntSeq = + iseq <| seq { for i in 1..10 do + yield i} + + let foldInt = ISeq.fold funcInt 1 IntSeq + if foldInt <> 56 then Assert.Fail() + + // string ISeq + let funcStr (x:string) (y:string) = x+y + let strSeq = iseq ["B"; "C"; "D" ; "E"] + let foldStr = ISeq.fold funcStr "A" strSeq + + if foldStr <> "ABCDE" then Assert.Fail() + + + // Empty ISeq + let emptySeq = ISeq.empty + let foldEmpty = ISeq.fold funcInt 1 emptySeq + if foldEmpty <> 1 then Assert.Fail() + + //// null ISeq + //let nullSeq:iseq<'a> = null + + //CheckThrowsArgumentNullException (fun () -> ISeq.fold funcInt 1 nullSeq |> ignore) + () + + + + [] + member this.Fold2() = + Assert.AreEqual([(3,5); (2,3); (1,1)],ISeq.fold2 (fun acc x y -> (x,y)::acc) [] (iseq [ 1..3 ]) (iseq [1..2..6])) + + // integer List + let funcInt x y z = x + y + z + let resultInt = ISeq.fold2 funcInt 9 (iseq [ 1..10 ]) (iseq [1..2..20]) + Assert.AreEqual(164, resultInt) + + // string List + let funcStr x y z = x + y + z + let resultStr = ISeq.fold2 funcStr "*" (iseq ["a"; "b"; "c" ; "d" ]) (iseq ["A"; "B"; "C" ; "D" ] ) + Assert.AreEqual("*aAbBcCdD", resultStr) + + // empty List + let emptyArr:int list = [ ] + let resultEpt = ISeq.fold2 funcInt 5 (iseq emptyArr) (iseq emptyArr) + Assert.AreEqual(5, resultEpt) + + Assert.AreEqual(0,ISeq.fold2 funcInt 0 ISeq.empty (iseq [1])) + Assert.AreEqual(-1,ISeq.fold2 funcInt -1 (iseq [1]) ISeq.empty) + + Assert.AreEqual(2,ISeq.fold2 funcInt 0 (iseq [1;2]) (iseq [1])) + Assert.AreEqual(4,ISeq.fold2 funcInt 0 (iseq [1]) (iseq [3;6])) + + //// null ISeq + //let nullSeq:iseq<'a> = null + + //CheckThrowsArgumentNullException (fun () -> ISeq.fold2 funcInt 0 nullSeq (iseq [1]) |> ignore) + //CheckThrowsArgumentNullException (fun () -> ISeq.fold2 funcInt 0 (iseq [1]) nullSeq |> ignore) + () + + [] + member this.FoldBack() = + // int ISeq + let funcInt x y = x-y + let IntSeq = iseq <| seq { 1..4 } + let foldInt = ISeq.foldBack funcInt IntSeq 6 + Assert.AreEqual((1-(2-(3-(4-6)))), foldInt) + + // string ISeq + let funcStr (x:string) (y:string) = y.Remove(0,x.Length) + let strSeq = iseq [ "A"; "B"; "C"; "D" ] + let foldStr = ISeq.foldBack funcStr strSeq "ABCDE" + Assert.AreEqual("E", foldStr) + + // single element + let funcStr2 elem acc = sprintf "%s%s" elem acc + let strSeq2 = iseq [ "A" ] + let foldStr2 = ISeq.foldBack funcStr2 strSeq2 "X" + Assert.AreEqual("AX", foldStr2) + + // Empty ISeq + let emptySeq = ISeq.empty + let foldEmpty = ISeq.foldBack funcInt emptySeq 1 + Assert.AreEqual(1, foldEmpty) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.foldBack funcInt nullSeq 1 |> ignore) + + // Validate that foldBack with the cons operator and the empty list returns a copy of the sequence + let cons x y = x :: y + let identityFoldr = ISeq.foldBack cons IntSeq [] + Assert.AreEqual([1;2;3;4], identityFoldr) + + () + + [] + member this.foldBack2() = + // int ISeq + let funcInt x y z = x + y + z + let intSeq = iseq <| seq { 1..10 } + let resultInt = ISeq.foldBack2 funcInt intSeq (iseq <| seq { 1..2..20 }) 9 + Assert.AreEqual(164, resultInt) + + // string ISeq + let funcStr = sprintf "%s%s%s" + let strSeq = iseq [ "A"; "B"; "C"; "D" ] + let resultStr = ISeq.foldBack2 funcStr strSeq (iseq [ "a"; "b"; "c"; "d"]) "*" + Assert.AreEqual("AaBbCcDd*", resultStr) + + // single element + let strSeqSingle = iseq [ "X" ] + Assert.AreEqual("XAZ", ISeq.foldBack2 funcStr strSeqSingle strSeq "Z") + Assert.AreEqual("AXZ", ISeq.foldBack2 funcStr strSeq strSeqSingle "Z") + Assert.AreEqual("XYZ", ISeq.foldBack2 funcStr strSeqSingle (iseq [ "Y" ]) "Z") + + // empty ISeq + let emptySeq = ISeq.empty + Assert.AreEqual(1, ISeq.foldBack2 funcInt emptySeq emptySeq 1) + Assert.AreEqual(1, ISeq.foldBack2 funcInt emptySeq intSeq 1) + Assert.AreEqual(1, ISeq.foldBack2 funcInt intSeq emptySeq 1) + + // infinite ISeq + let infiniteSeq = ISeq.initInfinite (fun i -> 2 * i + 1) + Assert.AreEqual(164, ISeq.foldBack2 funcInt intSeq infiniteSeq 9) + Assert.AreEqual(164, ISeq.foldBack2 funcInt infiniteSeq intSeq 9) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.foldBack2 funcInt nullSeq intSeq 1 |> ignore) + //CheckThrowsArgumentNullException (fun () -> ISeq.foldBack2 funcInt intSeq nullSeq 1 |> ignore) + //CheckThrowsArgumentNullException (fun () -> ISeq.foldBack2 funcInt nullSeq nullSeq 1 |> ignore) + + () + + [] + member this.ForAll() = + + let funcInt x = if x%2 = 0 then true else false + let IntSeq = + iseq <| seq { for i in 1..10 do + yield i*2} + let for_allInt = ISeq.forall funcInt IntSeq + + if for_allInt <> true then Assert.Fail() + + + // string ISeq + let funcStr (x:string) = x.Contains("a") + let strSeq = iseq ["a"; "ab"; "abc" ; "abcd"] + let for_allStr = ISeq.forall funcStr strSeq + + if for_allStr <> true then Assert.Fail() + + + // Empty ISeq + let emptySeq = ISeq.empty + let for_allEmpty = ISeq.forall funcInt emptySeq + + if for_allEmpty <> true then Assert.Fail() + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.forall funcInt nullSeq |> ignore) + () + + [] + member this.ForAll2() = + + let funcInt x y = if (x+y)%2 = 0 then true else false + let IntSeq = + iseq <| seq { for i in 1..10 do + yield i} + + let for_all2Int = ISeq.forall2 funcInt IntSeq IntSeq + + if for_all2Int <> true then Assert.Fail() + + // string ISeq + let funcStr (x:string) (y:string) = (x+y).Length = 5 + let strSeq1 = iseq ["a"; "ab"; "abc" ; "abcd"] + let strSeq2 = iseq ["abcd"; "abc"; "ab" ; "a"] + let for_all2Str = ISeq.forall2 funcStr strSeq1 strSeq2 + + if for_all2Str <> true then Assert.Fail() + + // Empty ISeq + let emptySeq = ISeq.empty + let for_all2Empty = ISeq.forall2 funcInt emptySeq emptySeq + + if for_all2Empty <> true then Assert.Fail() + + //// null ISeq + //let nullSeq:iseq<'a> = null + + //CheckThrowsArgumentNullException (fun () -> ISeq.forall2 funcInt nullSeq nullSeq |> ignore) + + [] + member this.GroupBy() = + + let funcInt x = x%5 + + let IntSeq = + iseq <| seq { for i in 0 .. 9 do + yield i } + + let group_byInt = ISeq.groupByVal funcInt IntSeq |> ISeq.map (fun (i, v) -> i, ISeq.toList v) + + let expectedIntSeq = + iseq <| seq { for i in 0..4 do + yield i, [i; i+5] } + + VerifySeqsEqual group_byInt expectedIntSeq + + // string ISeq + let funcStr (x:string) = x.Length + let strSeq = iseq ["length7"; "length 8"; "length7" ; "length 9"] + + let group_byStr = ISeq.groupByVal funcStr strSeq |> ISeq.map (fun (i, v) -> i, ISeq.toList v) + let expectedStrSeq = + iseq <| seq { + yield 7, ["length7"; "length7"] + yield 8, ["length 8"] + yield 9, ["length 9"] } + + VerifySeqsEqual expectedStrSeq group_byStr + + // Empty ISeq + let emptySeq = ISeq.empty + let group_byEmpty = ISeq.groupByVal funcInt emptySeq + let expectedEmptySeq = iseq [] + + VerifySeqsEqual expectedEmptySeq group_byEmpty + + //// null ISeq + //let nullSeq:iseq<'a> = null + //let group_byNull = ISeq.groupBy funcInt nullSeq + //CheckThrowsArgumentNullException (fun () -> ISeq.iter (fun _ -> ()) group_byNull) + () + + [] + member this.DisposalOfUnstartedEnumerator() = + let run = ref false + let f() = iseq <| seq { + try + () + finally + run := true + } + + f().GetEnumerator().Dispose() + Assert.IsFalse(!run) + + [] + member this.WeirdLocalNames() = + + let f pc = iseq <| seq { + yield pc + yield (pc+1) + yield (pc+2) + } + + let l = f 3 |> ISeq.toList + Assert.AreEqual([3;4;5], l) + + let f i = iseq <| seq { + let pc = i*2 + yield pc + yield (pc+1) + yield (pc+2) + } + let l = f 3 |> ISeq.toList + Assert.AreEqual([6;7;8], l) + + [] + member this.Contains() = + + // Integer ISeq + let intSeq = iseq <| seq { 0..9 } + + let ifContainsInt = ISeq.contains 5 intSeq + + Assert.IsTrue(ifContainsInt) + + // String ISeq + let strSeq = iseq ["key"; "blank key"] + + let ifContainsStr = ISeq.contains "key" strSeq + + Assert.IsTrue(ifContainsStr) + + // Empty ISeq + let emptySeq = ISeq.empty + let ifContainsEmpty = ISeq.contains 5 emptySeq + + Assert.IsFalse(ifContainsEmpty) + + //// null ISeq + //let nullSeq:iseq<'a> = null + + //CheckThrowsArgumentNullException (fun () -> ISeq.contains 5 nullSeq |> ignore) diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ISeqModule2.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ISeqModule2.fs new file mode 100644 index 00000000000..e6a16911496 --- /dev/null +++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ISeqModule2.fs @@ -0,0 +1,1841 @@ +// 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 FSharp.Core.Unittests.FSharp_Core.Microsoft_FSharp_Collections + +open System +open NUnit.Framework + +open FSharp.Core.Unittests.LibraryTestFx + +//type iseq<'a> = ISeq.Core.ISeq<'a> + +type ISeqWindowedTestInput<'t> = + { + InputSeq : iseq<'t> + WindowSize : int + ExpectedSeq : iseq<'t[]> + Exception : Type option + } + +[] +type ISeqModule2() = + let iseq (x:seq<_>) = x |> ISeq.ofSeq + + [] + member this.Hd() = + + let IntSeq = + iseq <| seq { for i in 0 .. 9 do + yield i } + + if ISeq.head IntSeq <> 0 then Assert.Fail() + + // string ISeq + let strSeq = iseq ["first"; "second"; "third"] + if ISeq.head strSeq <> "first" then Assert.Fail() + + // Empty ISeq + let emptySeq = ISeq.empty + CheckThrowsArgumentException ( fun() -> ISeq.head emptySeq) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () ->ISeq.head nullSeq) + () + + [] + member this.TryHead() = + // int ISeq + let IntSeq = + iseq <| seq { for i in 0 .. 9 -> i } + + let intResult = ISeq.tryHead IntSeq + + // string ISeq + let strResult = ISeq.tryHead (iseq ["first"; "second"; "third"]) + Assert.AreEqual("first", strResult.Value) + + // Empty ISeq + let emptyResult = ISeq.tryHead ISeq.empty + Assert.AreEqual(None, emptyResult) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () ->ISeq.head nullSeq) + () + + [] + member this.Tl() = + // integer iseq + let resultInt = ISeq.tail <| (iseq <| seq { 1..10 } ) + Assert.AreEqual(Array.ofSeq (iseq <| seq { 2..10 }), Array.ofSeq resultInt) + + // string iseq + let resultStr = ISeq.tail <| (iseq <| seq { yield "a"; yield "b"; yield "c"; yield "d" }) + Assert.AreEqual(Array.ofSeq (iseq <| seq { yield "b"; yield "c" ; yield "d" }), Array.ofSeq resultStr) + + // 1-element iseq + let resultStr2 = ISeq.tail <| (iseq <| seq { yield "a" }) + Assert.AreEqual(Array.ofSeq (ISeq.empty : iseq), Array.ofSeq resultStr2) + + //CheckThrowsArgumentNullException(fun () -> ISeq.tail null |> ignore) + CheckThrowsArgumentException(fun () -> ISeq.tail ISeq.empty |> ISeq.iter (fun _ -> failwith "Should not be reached")) + () + + [] + member this.Last() = + + let IntSeq = + iseq <| seq { for i in 0 .. 9 do + yield i } + + if ISeq.last IntSeq <> 9 then Assert.Fail() + + // string ISeq + let strSeq = iseq ["first"; "second"; "third"] + if ISeq.last strSeq <> "third" then Assert.Fail() + + // Empty ISeq + let emptySeq = ISeq.empty + CheckThrowsArgumentException ( fun() -> ISeq.last emptySeq) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () ->ISeq.last nullSeq) + () + + [] + member this.TryLast() = + + let IntSeq = + iseq <| seq { for i in 0 .. 9 -> i } + + let intResult = ISeq.tryLast IntSeq + Assert.AreEqual(9, intResult.Value) + + // string ISeq + let strResult = ISeq.tryLast (iseq ["first"; "second"; "third"]) + Assert.AreEqual("third", strResult.Value) + + // Empty ISeq + let emptyResult = ISeq.tryLast ISeq.empty + Assert.IsTrue(emptyResult.IsNone) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () ->ISeq.tryLast nullSeq |> ignore) + () + + [] + member this.ExactlyOne() = + + let IntSeq = + iseq <| seq { for i in 7 .. 7 do + yield i } + + if ISeq.exactlyOne IntSeq <> 7 then Assert.Fail() + + // string ISeq + let strSeq = iseq ["second"] + if ISeq.exactlyOne strSeq <> "second" then Assert.Fail() + + // Empty ISeq + let emptySeq = ISeq.empty + CheckThrowsArgumentException ( fun() -> ISeq.exactlyOne emptySeq) + + // non-singleton ISeq + let emptySeq = ISeq.empty + CheckThrowsArgumentException ( fun() -> ISeq.exactlyOne (iseq [ 0 .. 1 ]) |> ignore ) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () ->ISeq.exactlyOne nullSeq) + () + + + [] + member this.Init() = + + let funcInt x = x + let init_finiteInt = ISeq.init 9 funcInt + let expectedIntSeq = iseq [ 0..8] + + VerifySeqsEqual expectedIntSeq init_finiteInt + + + // string ISeq + let funcStr x = x.ToString() + let init_finiteStr = ISeq.init 5 funcStr + let expectedStrSeq = iseq ["0";"1";"2";"3";"4"] + + VerifySeqsEqual expectedStrSeq init_finiteStr + + // null ISeq + let funcNull x = null + let init_finiteNull = ISeq.init 3 funcNull + let expectedNullSeq = iseq [ null;null;null] + + VerifySeqsEqual expectedNullSeq init_finiteNull + () + + [] + member this.InitInfinite() = + + let funcInt x = x + let init_infiniteInt = ISeq.initInfinite funcInt + let resultint = ISeq.find (fun x -> x =100) init_infiniteInt + + Assert.AreEqual(100,resultint) + + + // string ISeq + let funcStr x = x.ToString() + let init_infiniteStr = ISeq.initInfinite funcStr + let resultstr = ISeq.find (fun x -> x = "100") init_infiniteStr + + Assert.AreEqual("100",resultstr) + + + [] + member this.IsEmpty() = + + //iseq int + let seqint = iseq [1;2;3] + let is_emptyInt = ISeq.isEmpty seqint + + Assert.IsFalse(is_emptyInt) + + //iseq str + let seqStr = iseq["first";"second"] + let is_emptyStr = ISeq.isEmpty seqStr + + Assert.IsFalse(is_emptyInt) + + //iseq empty + let seqEmpty = ISeq.empty + let is_emptyEmpty = ISeq.isEmpty seqEmpty + Assert.IsTrue(is_emptyEmpty) + + ////iseq null + //let seqnull:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.isEmpty seqnull |> ignore) + () + + [] + member this.Iter() = + //iseq int + let seqint = iseq [ 1..3] + let cacheint = ref 0 + + let funcint x = cacheint := !cacheint + x + ISeq.iter funcint seqint + Assert.AreEqual(6,!cacheint) + + //iseq str + let seqStr = iseq ["first";"second"] + let cachestr =ref "" + let funcstr x = cachestr := !cachestr+x + ISeq.iter funcstr seqStr + + Assert.AreEqual("firstsecond",!cachestr) + + // empty array + let emptyseq = ISeq.empty + let resultEpt = ref 0 + ISeq.iter (fun x -> Assert.Fail()) emptyseq + + //// null seqay + //let nullseq:iseq<'a> = null + + //CheckThrowsArgumentNullException (fun () -> ISeq.iter funcint nullseq |> ignore) + () + + [] + member this.Iter2() = + + //iseq int + let seqint = iseq [ 1..3] + let cacheint = ref 0 + + let funcint x y = cacheint := !cacheint + x+y + ISeq.iter2 funcint seqint seqint + Assert.AreEqual(12,!cacheint) + + //iseq str + let seqStr = iseq ["first";"second"] + let cachestr =ref "" + let funcstr x y = cachestr := !cachestr+x+y + ISeq.iter2 funcstr seqStr seqStr + + Assert.AreEqual("firstfirstsecondsecond",!cachestr) + + // empty array + let emptyseq = ISeq.empty + let resultEpt = ref 0 + ISeq.iter2 (fun x y-> Assert.Fail()) emptyseq emptyseq + + //// null seqay + //let nullseq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.iter2 funcint nullseq nullseq |> ignore) + + () + + [] + member this.Iteri() = + + // iseq int + let seqint = iseq [ 1..10] + let cacheint = ref 0 + + let funcint x y = cacheint := !cacheint + x+y + ISeq.iteri funcint seqint + Assert.AreEqual(100,!cacheint) + + // iseq str + let seqStr = iseq ["first";"second"] + let cachestr =ref 0 + let funcstr (x:int) (y:string) = cachestr := !cachestr+ x + y.Length + ISeq.iteri funcstr seqStr + + Assert.AreEqual(12,!cachestr) + + // empty array + let emptyseq = ISeq.empty + let resultEpt = ref 0 + ISeq.iteri funcint emptyseq + Assert.AreEqual(0,!resultEpt) + + //// null seqay + //let nullseq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.iteri funcint nullseq |> ignore) + () + + [] + member this.Iteri2() = + + //iseq int + let seqint = iseq [ 1..3] + let cacheint = ref 0 + + let funcint x y z = cacheint := !cacheint + x + y + z + ISeq.iteri2 funcint seqint seqint + Assert.AreEqual(15,!cacheint) + + //iseq str + let seqStr = iseq ["first";"second"] + let cachestr = ref 0 + let funcstr (x:int) (y:string) (z:string) = cachestr := !cachestr + x + y.Length + z.Length + ISeq.iteri2 funcstr seqStr seqStr + + Assert.AreEqual(23,!cachestr) + + // empty iseq + let emptyseq = ISeq.empty + let resultEpt = ref 0 + ISeq.iteri2 (fun x y z -> Assert.Fail()) emptyseq emptyseq + + //// null iseq + //let nullseq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.iteri2 funcint nullseq nullseq |> ignore) + + // len1 <> len2 + let shorterSeq = iseq <| seq { 1..3 } + let longerSeq = iseq <| seq { 2..2..100 } + + let testSeqLengths seq1 seq2 = + let cache = ref 0 + let f x y z = cache := !cache + x + y + z + ISeq.iteri2 f seq1 seq2 + !cache + + Assert.AreEqual(21, testSeqLengths shorterSeq longerSeq) + Assert.AreEqual(21, testSeqLengths longerSeq shorterSeq) + + () + + [] + member this.Length() = + + // integer iseq + let resultInt = ISeq.length (iseq {1..8}) + if resultInt <> 8 then Assert.Fail() + + // string ISeq + let resultStr = ISeq.length (iseq ["Lists"; "are"; "commonly" ; "list" ]) + if resultStr <> 4 then Assert.Fail() + + // empty ISeq + let resultEpt = ISeq.length ISeq.empty + if resultEpt <> 0 then Assert.Fail() + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.length nullSeq |> ignore) + + () + + [] + member this.Map() = + + // integer ISeq + let funcInt x = + match x with + | _ when x % 2 = 0 -> 10*x + | _ -> x + + let resultInt = ISeq.map funcInt (iseq { 1..10 }) + let expectedint = iseq [1;20;3;40;5;60;7;80;9;100] + + VerifySeqsEqual expectedint resultInt + + // string ISeq + let funcStr (x:string) = x.ToLower() + let resultStr = ISeq.map funcStr (iseq ["Lists"; "Are"; "Commonly" ; "List" ]) + let expectedSeq = iseq ["lists"; "are"; "commonly" ; "list"] + + VerifySeqsEqual expectedSeq resultStr + + // empty ISeq + let resultEpt = ISeq.map funcInt ISeq.empty + VerifySeqsEqual ISeq.empty resultEpt + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.map funcStr nullSeq |> ignore) + + () + + [] + member this.Map2() = + // integer ISeq + let funcInt x y = x+y + let resultInt = ISeq.map2 funcInt (iseq { 1..10 }) (iseq {2..2..20}) + let expectedint = iseq [3;6;9;12;15;18;21;24;27;30] + + VerifySeqsEqual expectedint resultInt + + // string ISeq + let funcStr (x:int) (y:string) = x+y.Length + let resultStr = ISeq.map2 funcStr (iseq[3;6;9;11]) (iseq ["Lists"; "Are"; "Commonly" ; "List" ]) + let expectedSeq = iseq [8;9;17;15] + + VerifySeqsEqual expectedSeq resultStr + + // empty ISeq + let resultEpt = ISeq.map2 funcInt ISeq.empty ISeq.empty + VerifySeqsEqual ISeq.empty resultEpt + + //// null ISeq + //let nullSeq:iseq<'a> = null + //let validSeq = iseq [1] + //CheckThrowsArgumentNullException (fun () -> ISeq.map2 funcInt nullSeq validSeq |> ignore) + + () + + [] + member this.Map3() = + // Integer iseq + let funcInt a b c = (a + b) * c + let resultInt = ISeq.map3 funcInt (iseq { 1..8 }) (iseq { 2..9 }) (iseq { 3..10 }) + let expectedInt = iseq [9; 20; 35; 54; 77; 104; 135; 170] + VerifySeqsEqual expectedInt resultInt + + // First iseq is shorter + VerifySeqsEqual (iseq [9; 20]) (ISeq.map3 funcInt (iseq { 1..2 }) (iseq { 2..9 }) (iseq { 3..10 })) + // Second iseq is shorter + VerifySeqsEqual (iseq [9; 20; 35]) (ISeq.map3 funcInt (iseq { 1..8 }) (iseq { 2..4 }) (iseq { 3..10 })) + // Third iseq is shorter + VerifySeqsEqual (iseq [9; 20; 35; 54]) (ISeq.map3 funcInt (iseq { 1..8 }) (iseq { 2..6 }) (iseq { 3..6 })) + + // String iseq + let funcStr a b c = a + b + c + let resultStr = ISeq.map3 funcStr (iseq ["A";"B";"C";"D"]) (iseq ["a";"b";"c";"d"]) (iseq ["1";"2";"3";"4"]) + let expectedStr = iseq ["Aa1";"Bb2";"Cc3";"Dd4"] + VerifySeqsEqual expectedStr resultStr + + // Empty iseq + let resultEmpty = ISeq.map3 funcStr ISeq.empty ISeq.empty ISeq.empty + VerifySeqsEqual ISeq.empty resultEmpty + + //// Null iseq + //let nullSeq = null : iseq<_> + //let nonNullSeq = iseq [1] + //CheckThrowsArgumentNullException (fun () -> ISeq.map3 funcInt nullSeq nonNullSeq nullSeq |> ignore) + + () + + [] + member this.MapFold() = + // integer ISeq + let funcInt acc x = if x % 2 = 0 then 10*x, acc + 1 else x, acc + let resultInt,resultIntAcc = ISeq.mapFold funcInt 100 <| (iseq <| seq { 1..10 }) + VerifySeqsEqual (iseq [ 1;20;3;40;5;60;7;80;9;100 ]) resultInt + Assert.AreEqual(105, resultIntAcc) + + // string ISeq + let funcStr acc (x:string) = match x.Length with 0 -> "empty", acc | _ -> x.ToLower(), sprintf "%s%s" acc x + let resultStr,resultStrAcc = ISeq.mapFold funcStr "" <| iseq [ "";"BB";"C";"" ] + VerifySeqsEqual (iseq [ "empty";"bb";"c";"empty" ]) resultStr + Assert.AreEqual("BBC", resultStrAcc) + + // empty ISeq + let resultEpt,resultEptAcc = ISeq.mapFold funcInt 100 ISeq.empty + VerifySeqsEqual ISeq.empty resultEpt + Assert.AreEqual(100, resultEptAcc) + + //// null ISeq + //let nullArr = null:iseq + //CheckThrowsArgumentNullException (fun () -> ISeq.mapFold funcStr "" nullArr |> ignore) + + () + + [] + member this.MapFoldBack() = + // integer ISeq + let funcInt x acc = if acc < 105 then 10*x, acc + 2 else x, acc + let resultInt,resultIntAcc = ISeq.mapFoldBack funcInt (iseq <| seq { 1..10 }) 100 + VerifySeqsEqual (iseq [ 1;2;3;4;5;6;7;80;90;100 ]) resultInt + Assert.AreEqual(106, resultIntAcc) + + // string ISeq + let funcStr (x:string) acc = match x.Length with 0 -> "empty", acc | _ -> x.ToLower(), sprintf "%s%s" acc x + let resultStr,resultStrAcc = ISeq.mapFoldBack funcStr (iseq [ "";"BB";"C";"" ]) "" + VerifySeqsEqual (iseq [ "empty";"bb";"c";"empty" ]) resultStr + Assert.AreEqual("CBB", resultStrAcc) + + // empty ISeq + let resultEpt,resultEptAcc = ISeq.mapFoldBack funcInt ISeq.empty 100 + VerifySeqsEqual ISeq.empty resultEpt + Assert.AreEqual(100, resultEptAcc) + + //// null ISeq + //let nullArr = null:iseq + //CheckThrowsArgumentNullException (fun () -> ISeq.mapFoldBack funcStr nullArr "" |> ignore) + + () + + member private this.MapWithSideEffectsTester (map : (int -> int) -> iseq -> iseq) expectExceptions = + let i = ref 0 + let f x = i := !i + 1; x*x + let e = ((iseq [1;2]) |> map f).GetEnumerator() + + if expectExceptions then + CheckThrowsInvalidOperationExn (fun _ -> e.Current|>ignore) + Assert.AreEqual(0, !i) + if not (e.MoveNext()) then Assert.Fail() + Assert.AreEqual(1, !i) + let _ = e.Current + Assert.AreEqual(1, !i) + let _ = e.Current + Assert.AreEqual(1, !i) + + if not (e.MoveNext()) then Assert.Fail() + Assert.AreEqual(2, !i) + let _ = e.Current + Assert.AreEqual(2, !i) + let _ = e.Current + Assert.AreEqual(2, !i) + + if e.MoveNext() then Assert.Fail() + Assert.AreEqual(2, !i) + if expectExceptions then + CheckThrowsInvalidOperationExn (fun _ -> e.Current |> ignore) + Assert.AreEqual(2, !i) + + + i := 0 + let e = ((iseq []) |> map f).GetEnumerator() + if e.MoveNext() then Assert.Fail() + Assert.AreEqual(0,!i) + if e.MoveNext() then Assert.Fail() + Assert.AreEqual(0,!i) + + + member private this.MapWithExceptionTester (map : (int -> int) -> iseq -> iseq) = + let raiser x = if x > 0 then raise(NotSupportedException()) else x + let e = (map raiser (iseq [0; 1])).GetEnumerator() + Assert.IsTrue(e.MoveNext()) // should not throw + Assert.AreEqual(0, e.Current) + CheckThrowsNotSupportedException(fun _ -> e.MoveNext() |> ignore) + Assert.AreEqual(0, e.Current) // should not throw + + [] + member this.MapWithSideEffects () = + this.MapWithSideEffectsTester ISeq.map true + + [] + member this.MapWithException () = + this.MapWithExceptionTester ISeq.map + + + [] + member this.SingletonCollectWithSideEffects () = + this.MapWithSideEffectsTester (fun f-> ISeq.collect (f >> ISeq.singleton)) true + + [] + member this.SingletonCollectWithException () = + this.MapWithExceptionTester (fun f-> ISeq.collect (f >> ISeq.singleton)) + +#if !FX_NO_LINQ + [] + member this.SystemLinqSelectWithSideEffects () = + this.MapWithSideEffectsTester (fun f s -> iseq <| System.Linq.Enumerable.Select(s, Func<_,_>(f))) false + + [] + member this.SystemLinqSelectWithException () = + this.MapWithExceptionTester (fun f s -> iseq <| System.Linq.Enumerable.Select(s, Func<_,_>(f))) +#endif + + [] + member this.MapiWithSideEffects () = + let i = ref 0 + let f _ x = i := !i + 1; x*x + let e = ((iseq [1;2]) |> ISeq.mapi f).GetEnumerator() + + CheckThrowsInvalidOperationExn (fun _ -> e.Current|>ignore) + Assert.AreEqual(0, !i) + if not (e.MoveNext()) then Assert.Fail() + Assert.AreEqual(1, !i) + let _ = e.Current + Assert.AreEqual(1, !i) + let _ = e.Current + Assert.AreEqual(1, !i) + + if not (e.MoveNext()) then Assert.Fail() + Assert.AreEqual(2, !i) + let _ = e.Current + Assert.AreEqual(2, !i) + let _ = e.Current + Assert.AreEqual(2, !i) + + if e.MoveNext() then Assert.Fail() + Assert.AreEqual(2, !i) + CheckThrowsInvalidOperationExn (fun _ -> e.Current|>ignore) + Assert.AreEqual(2, !i) + + i := 0 + let e = ((iseq []) |> ISeq.mapi f).GetEnumerator() + if e.MoveNext() then Assert.Fail() + Assert.AreEqual(0,!i) + if e.MoveNext() then Assert.Fail() + Assert.AreEqual(0,!i) + + [] + member this.Map2WithSideEffects () = + let i = ref 0 + let f x y = i := !i + 1; x*x + let e = (ISeq.map2 f (iseq [1;2]) (iseq [1;2])).GetEnumerator() + + CheckThrowsInvalidOperationExn (fun _ -> e.Current|>ignore) + Assert.AreEqual(0, !i) + if not (e.MoveNext()) then Assert.Fail() + Assert.AreEqual(1, !i) + let _ = e.Current + Assert.AreEqual(1, !i) + let _ = e.Current + Assert.AreEqual(1, !i) + + if not (e.MoveNext()) then Assert.Fail() + Assert.AreEqual(2, !i) + let _ = e.Current + Assert.AreEqual(2, !i) + let _ = e.Current + Assert.AreEqual(2, !i) + + if e.MoveNext() then Assert.Fail() + Assert.AreEqual(2,!i) + CheckThrowsInvalidOperationExn (fun _ -> e.Current|>ignore) + Assert.AreEqual(2, !i) + + i := 0 + let e = (ISeq.map2 f (iseq []) (iseq [])).GetEnumerator() + if e.MoveNext() then Assert.Fail() + Assert.AreEqual(0,!i) + if e.MoveNext() then Assert.Fail() + Assert.AreEqual(0,!i) + + [] + member this.Mapi2WithSideEffects () = + let i = ref 0 + let f _ x y = i := !i + 1; x*x + let e = (ISeq.mapi2 f (iseq [1;2]) (iseq [1;2])).GetEnumerator() + + CheckThrowsInvalidOperationExn (fun _ -> e.Current|>ignore) + Assert.AreEqual(0, !i) + if not (e.MoveNext()) then Assert.Fail() + Assert.AreEqual(1, !i) + let _ = e.Current + Assert.AreEqual(1, !i) + let _ = e.Current + Assert.AreEqual(1, !i) + + if not (e.MoveNext()) then Assert.Fail() + Assert.AreEqual(2, !i) + let _ = e.Current + Assert.AreEqual(2, !i) + let _ = e.Current + Assert.AreEqual(2, !i) + + if e.MoveNext() then Assert.Fail() + Assert.AreEqual(2,!i) + CheckThrowsInvalidOperationExn (fun _ -> e.Current|>ignore) + Assert.AreEqual(2, !i) + + i := 0 + let e = (ISeq.mapi2 f (iseq []) (iseq [])).GetEnumerator() + if e.MoveNext() then Assert.Fail() + Assert.AreEqual(0,!i) + if e.MoveNext() then Assert.Fail() + Assert.AreEqual(0,!i) + + [] + member this.Collect() = + // integer ISeq + let funcInt x = iseq [x+1] + let resultInt = ISeq.collect funcInt (iseq { 1..10 }) + + let expectedint = iseq <| seq {2..11} + + VerifySeqsEqual expectedint resultInt + +//#if !FX_NO_CHAR_PARSE +// // string ISeq +// let funcStr (y:string) = y+"ist" + +// let resultStr = ISeq.collect funcStr (iseq ["L"]) + + +// let expectedSeq = iseq ['L';'i';'s';'t'] + +// VerifySeqsEqual expectedSeq resultStr +//#endif + // empty ISeq + let resultEpt = ISeq.collect funcInt ISeq.empty + VerifySeqsEqual ISeq.empty resultEpt + + //// null ISeq + //let nullSeq:iseq<'a> = null + + //CheckThrowsArgumentNullException (fun () -> ISeq.collect funcInt nullSeq |> ignore) + + () + + [] + member this.Mapi() = + + // integer ISeq + let funcInt x y = x+y + let resultInt = ISeq.mapi funcInt (iseq { 10..2..20 } ) + let expectedint = iseq [10;13;16;19;22;25] + + VerifySeqsEqual expectedint resultInt + + // string ISeq + let funcStr (x:int) (y:string) =x+y.Length + + let resultStr = ISeq.mapi funcStr (iseq ["Lists"; "Are"; "Commonly" ; "List" ]) + let expectedStr = iseq [5;4;10;7] + + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.mapi funcInt ISeq.empty + VerifySeqsEqual ISeq.empty resultEpt + + //// null ISeq + //let nullSeq:iseq<'a> = null + + //CheckThrowsArgumentNullException (fun () -> ISeq.mapi funcInt nullSeq |> ignore) + + () + + [] + member this.Mapi2() = + // integer ISeq + let funcInt x y z = x+y+z + let resultInt = ISeq.mapi2 funcInt (iseq { 1..10 }) (iseq {2..2..20}) + let expectedint = iseq [3;7;11;15;19;23;27;31;35;39] + + VerifySeqsEqual expectedint resultInt + + // string ISeq + let funcStr (x:int) (y:int) (z:string) = x+y+z.Length + let resultStr = ISeq.mapi2 funcStr (iseq[3;6;9;11]) (iseq ["Lists"; "Are"; "Commonly" ; "List" ]) + let expectedSeq = iseq [8;10;19;18] + + VerifySeqsEqual expectedSeq resultStr + + // empty ISeq + let resultEpt = ISeq.mapi2 funcInt ISeq.empty ISeq.empty + VerifySeqsEqual ISeq.empty resultEpt + + //// null ISeq + //let nullSeq:iseq<'a> = null + //let validSeq = iseq [1] + //CheckThrowsArgumentNullException (fun () -> ISeq.mapi2 funcInt nullSeq validSeq |> ignore) + + // len1 <> len2 + let shorterSeq = iseq <| seq { 1..10 } + let longerSeq = iseq <| seq { 2..20 } + + let testSeqLengths seq1 seq2 = + let f x y z = x + y + z + ISeq.mapi2 f seq1 seq2 + + VerifySeqsEqual (iseq [3;6;9;12;15;18;21;24;27;30]) (testSeqLengths shorterSeq longerSeq) + VerifySeqsEqual (iseq [3;6;9;12;15;18;21;24;27;30]) (testSeqLengths longerSeq shorterSeq) + + [] + member this.Indexed() = + + // integer ISeq + let resultInt = ISeq.indexed (iseq { 10..2..20 }) + let expectedint = iseq [(0,10);(1,12);(2,14);(3,16);(4,18);(5,20)] + + VerifySeqsEqual expectedint resultInt + + // string ISeq + let resultStr = ISeq.indexed (iseq ["Lists"; "Are"; "Commonly"; "List" ]) + let expectedStr = iseq [(0,"Lists");(1,"Are");(2,"Commonly");(3,"List")] + + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.indexed ISeq.empty + VerifySeqsEqual ISeq.empty resultEpt + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.indexed nullSeq |> ignore) + + () + + [] + member this.Max() = + // integer ISeq + let resultInt = ISeq.max (iseq { 10..20 } ) + + Assert.AreEqual(20,resultInt) + + // string ISeq + + let resultStr = ISeq.max (iseq ["Lists"; "Are"; "MaxString" ; "List" ]) + Assert.AreEqual("MaxString",resultStr) + + // empty ISeq + CheckThrowsArgumentException(fun () -> ISeq.max ( ISeq.empty : iseq) |> ignore) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.max nullSeq |> ignore) + + () + + [] + member this.MaxBy() = + + // integer ISeq + let funcInt x = x % 8 + let resultInt = ISeq.maxBy funcInt (iseq { 2..2..20 } ) + Assert.AreEqual(6,resultInt) + + // string ISeq + let funcStr (x:string) =x.Length + let resultStr = ISeq.maxBy funcStr (iseq ["Lists"; "Are"; "Commonly" ; "List" ]) + Assert.AreEqual("Commonly",resultStr) + + // empty ISeq + CheckThrowsArgumentException (fun () -> ISeq.maxBy funcInt (ISeq.empty : iseq) |> ignore) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () ->ISeq.maxBy funcInt nullSeq |> ignore) + + () + + [] + member this.MinBy() = + + // integer ISeq + let funcInt x = x % 8 + let resultInt = ISeq.minBy funcInt (iseq { 2..2..20 } ) + Assert.AreEqual(8,resultInt) + + // string ISeq + let funcStr (x:string) =x.Length + let resultStr = ISeq.minBy funcStr (iseq ["Lists"; "Are"; "Commonly" ; "List" ]) + Assert.AreEqual("Are",resultStr) + + // empty ISeq + CheckThrowsArgumentException (fun () -> ISeq.minBy funcInt (ISeq.empty : iseq) |> ignore) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () ->ISeq.minBy funcInt nullSeq |> ignore) + + () + + + [] + member this.Min() = + + // integer ISeq + let resultInt = ISeq.min (iseq { 10..20 } ) + Assert.AreEqual(10,resultInt) + + // string ISeq + let resultStr = ISeq.min (iseq ["Lists"; "Are"; "minString" ; "List" ]) + Assert.AreEqual("Are",resultStr) + + // empty ISeq + CheckThrowsArgumentException (fun () -> ISeq.min (ISeq.empty : iseq) |> ignore) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.min nullSeq |> ignore) + + () + + [] + member this.Item() = + // integer ISeq + let resultInt = ISeq.item 3 (iseq { 10..20 }) + Assert.AreEqual(13, resultInt) + + // string ISeq + let resultStr = ISeq.item 2 (iseq ["Lists"; "Are"; "Cool" ; "List" ]) + Assert.AreEqual("Cool", resultStr) + + // empty ISeq + CheckThrowsArgumentException(fun () -> ISeq.item 0 (ISeq.empty : iseq) |> ignore) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () ->ISeq.item 3 nullSeq |> ignore) + + // Negative index + for i = -1 downto -10 do + CheckThrowsArgumentException (fun () -> ISeq.item i (iseq { 10 .. 20 }) |> ignore) + + // Out of range + for i = 11 to 20 do + CheckThrowsArgumentException (fun () -> ISeq.item i (iseq { 10 .. 20 }) |> ignore) + + [] + member this.``item should fail with correct number of missing elements``() = + try + ISeq.item 0 (iseq (Array.zeroCreate 0)) |> ignore + failwith "error expected" + with + | exn when exn.Message.Contains("seq was short by 1 element") -> () + + try + ISeq.item 2 (iseq (Array.zeroCreate 0)) |> ignore + failwith "error expected" + with + | exn when exn.Message.Contains("seq was short by 3 elements") -> () + + [] + member this.Of_Array() = + // integer ISeq + let resultInt = ISeq.ofArray [|1..10|] + let expectedInt = {1..10} + + VerifySeqsEqual expectedInt resultInt + + // string ISeq + let resultStr = ISeq.ofArray [|"Lists"; "Are"; "ofArrayString" ; "List" |] + let expectedStr = iseq ["Lists"; "Are"; "ofArrayString" ; "List" ] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.ofArray [| |] + VerifySeqsEqual resultEpt ISeq.empty + + () + + [] + member this.Of_List() = + // integer ISeq + let resultInt = ISeq.ofList [1..10] + let expectedInt = {1..10} + + VerifySeqsEqual expectedInt resultInt + + // string ISeq + + let resultStr =ISeq.ofList ["Lists"; "Are"; "ofListString" ; "List" ] + let expectedStr = iseq ["Lists"; "Are"; "ofListString" ; "List" ] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.ofList [] + VerifySeqsEqual resultEpt ISeq.empty + () + + + [] + member this.Pairwise() = + // integer ISeq + let resultInt = ISeq.pairwise (iseq {1..3}) + + let expectedInt = iseq [1,2;2,3] + + VerifySeqsEqual expectedInt resultInt + + // string ISeq + let resultStr =ISeq.pairwise (iseq ["str1"; "str2";"str3" ]) + let expectedStr = iseq ["str1","str2";"str2","str3"] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.pairwise (iseq [] ) + VerifySeqsEqual resultEpt ISeq.empty + + () + + [] + member this.Reduce() = + + // integer ISeq + let resultInt = ISeq.reduce (fun x y -> x/y) (iseq [5*4*3*2; 4;3;2;1]) + Assert.AreEqual(5,resultInt) + + // string ISeq + let resultStr = ISeq.reduce (fun (x:string) (y:string) -> x.Remove(0,y.Length)) (iseq ["ABCDE";"A"; "B"; "C" ; "D" ]) + Assert.AreEqual("E",resultStr) + + // empty ISeq + CheckThrowsArgumentException (fun () -> ISeq.reduce (fun x y -> x/y) ISeq.empty |> ignore) + + //// null ISeq + //let nullSeq : iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.reduce (fun (x:string) (y:string) -> x.Remove(0,y.Length)) nullSeq |> ignore) + () + + [] + member this.ReduceBack() = + // int ISeq + let funcInt x y = x - y + let IntSeq = iseq <| seq { 1..4 } + let reduceInt = ISeq.reduceBack funcInt IntSeq + Assert.AreEqual((1-(2-(3-4))), reduceInt) + + // string ISeq + let funcStr (x:string) (y:string) = y.Remove(0,x.Length) + let strSeq = iseq [ "A"; "B"; "C"; "D" ; "ABCDE" ] + let reduceStr = ISeq.reduceBack funcStr strSeq + Assert.AreEqual("E", reduceStr) + + // string ISeq + let funcStr2 elem acc = sprintf "%s%s" elem acc + let strSeq2 = iseq [ "A" ] + let reduceStr2 = ISeq.reduceBack funcStr2 strSeq2 + Assert.AreEqual("A", reduceStr2) + + // Empty ISeq + CheckThrowsArgumentException (fun () -> ISeq.reduceBack funcInt ISeq.empty |> ignore) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.reduceBack funcInt nullSeq |> ignore) + + () + + [] + member this.Rev() = + // integer ISeq + let resultInt = ISeq.rev (iseq [5;4;3;2;1]) + VerifySeqsEqual (iseq[1;2;3;4;5]) resultInt + + // string ISeq + let resultStr = ISeq.rev (iseq ["A"; "B"; "C" ; "D" ]) + VerifySeqsEqual (iseq["D";"C";"B";"A"]) resultStr + + // empty ISeq + VerifySeqsEqual ISeq.empty (ISeq.rev ISeq.empty) + + //// null ISeq + //let nullSeq : iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.rev nullSeq |> ignore) + () + + [] + member this.Scan() = + // integer ISeq + let funcInt x y = x+y + let resultInt = ISeq.scan funcInt 9 (iseq {1..10}) + let expectedInt = iseq [9;10;12;15;19;24;30;37;45;54;64] + VerifySeqsEqual expectedInt resultInt + + // string ISeq + let funcStr x y = x+y + let resultStr =ISeq.scan funcStr "x" (iseq ["str1"; "str2";"str3" ]) + + let expectedStr = iseq ["x";"xstr1"; "xstr1str2";"xstr1str2str3"] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.scan funcInt 5 ISeq.empty + + VerifySeqsEqual resultEpt (iseq [ 5]) + + //// null ISeq + //let seqNull:iseq<'a> = null + //CheckThrowsArgumentNullException(fun() -> ISeq.scan funcInt 5 seqNull |> ignore) + () + + [] + member this.ScanBack() = + // integer ISeq + let funcInt x y = x+y + let resultInt = ISeq.scanBack funcInt (iseq { 1..10 }) 9 + let expectedInt = iseq [64;63;61;58;54;49;43;36;28;19;9] + VerifySeqsEqual expectedInt resultInt + + // string ISeq + let funcStr x y = x+y + let resultStr = ISeq.scanBack funcStr (iseq ["A";"B";"C";"D"]) "X" + let expectedStr = iseq ["ABCDX";"BCDX";"CDX";"DX";"X"] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.scanBack funcInt ISeq.empty 5 + let expectedEpt = iseq [5] + VerifySeqsEqual expectedEpt resultEpt + + //// null ISeq + //let seqNull:iseq<'a> = null + //CheckThrowsArgumentNullException(fun() -> ISeq.scanBack funcInt seqNull 5 |> ignore) + + // exception cases + let funcEx x (s:'State) = raise <| new System.FormatException() : 'State + // calling scanBack with funcEx does not throw + let resultEx = ISeq.scanBack funcEx (iseq <| seq {1..10}) 0 + // reading from resultEx throws + CheckThrowsFormatException(fun() -> ISeq.head resultEx |> ignore) + + // Result consumes entire input sequence as soon as it is accesses an element + let i = ref 0 + let funcState x s = (i := !i + x); x+s + let resultState = ISeq.scanBack funcState (iseq <| seq {1..3}) 0 + Assert.AreEqual(0, !i) + use e = resultState.GetEnumerator() + Assert.AreEqual(6, !i) + + () + + [] + member this.Singleton() = + // integer ISeq + let resultInt = ISeq.singleton 1 + + let expectedInt = iseq [1] + VerifySeqsEqual expectedInt resultInt + + // string ISeq + let resultStr =ISeq.singleton "str1" + let expectedStr = iseq ["str1"] + VerifySeqsEqual expectedStr resultStr + + // null ISeq + let resultNull = ISeq.singleton null + let expectedNull = iseq [null] + VerifySeqsEqual expectedNull resultNull + () + + + [] + member this.Skip() = + + // integer ISeq + let resultInt = ISeq.skip 2 (iseq [1;2;3;4]) + let expectedInt = iseq [3;4] + VerifySeqsEqual expectedInt resultInt + + // string ISeq + let resultStr =ISeq.skip 2 (iseq ["str1";"str2";"str3";"str4"]) + let expectedStr = iseq ["str3";"str4"] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.skip 0 ISeq.empty + VerifySeqsEqual resultEpt ISeq.empty + + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.skip 1 null |> ignore) + () + + [] + member this.Skip_While() = + + // integer ISeq + let funcInt x = (x < 3) + let resultInt = ISeq.skipWhile funcInt (iseq [1;2;3;4;5;6]) + let expectedInt = iseq [3;4;5;6] + VerifySeqsEqual expectedInt resultInt + + // string ISeq + let funcStr (x:string) = x.Contains(".") + let resultStr =ISeq.skipWhile funcStr (iseq [".";"asdfasdf.asdfasdf";"";"";"";"";"";"";"";"";""]) + let expectedStr = iseq ["";"";"";"";"";"";"";"";""] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.skipWhile funcInt ISeq.empty + VerifySeqsEqual resultEpt ISeq.empty + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.skipWhile funcInt null |> ignore) + () + + [] + member this.Sort() = + + // integer ISeq + let resultInt = ISeq.sort (iseq [1;3;2;4;6;5;7]) + let expectedInt = {1..7} + VerifySeqsEqual expectedInt resultInt + + // string ISeq + + let resultStr =ISeq.sort (iseq ["str1";"str3";"str2";"str4"]) + let expectedStr = iseq ["str1";"str2";"str3";"str4"] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.sort ISeq.empty + VerifySeqsEqual resultEpt ISeq.empty + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.sort null |> ignore) + () + + [] + member this.SortBy() = + + // integer ISeq + let funcInt x = Math.Abs(x-5) + let resultInt = ISeq.sortBy funcInt (iseq [1;2;4;5;7]) + let expectedInt = iseq [5;4;7;2;1] + VerifySeqsEqual expectedInt resultInt + + // string ISeq + let funcStr (x:string) = x.IndexOf("key") + let resultStr =ISeq.sortBy funcStr (iseq ["st(key)r";"str(key)";"s(key)tr";"(key)str"]) + + let expectedStr = iseq ["(key)str";"s(key)tr";"st(key)r";"str(key)"] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.sortBy funcInt ISeq.empty + VerifySeqsEqual resultEpt ISeq.empty + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.sortBy funcInt null |> ignore) + () + + [] + member this.SortDescending() = + + // integer ISeq + let resultInt = ISeq.sortDescending (iseq [1;3;2;Int32.MaxValue;4;6;Int32.MinValue;5;7;0]) + let expectedInt = iseq <| seq { + yield Int32.MaxValue; + yield! iseq{ 7..-1..0 } + yield Int32.MinValue + } + VerifySeqsEqual expectedInt resultInt + + // string ISeq + + let resultStr = ISeq.sortDescending (iseq ["str1";null;"str3";"";"Str1";"str2";"str4"]) + let expectedStr = iseq ["str4";"str3";"str2";"str1";"Str1";"";null] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.sortDescending ISeq.empty + VerifySeqsEqual resultEpt ISeq.empty + + // tuple ISeq + let tupSeq = (iseq[(2,"a");(1,"d");(1,"b");(1,"a");(2,"x");(2,"b");(1,"x")]) + let resultTup = ISeq.sortDescending tupSeq + let expectedTup = (iseq[(2,"x");(2,"b");(2,"a");(1,"x");(1,"d");(1,"b");(1,"a")]) + VerifySeqsEqual expectedTup resultTup + + // float ISeq + let minFloat,maxFloat,epsilon = System.Double.MinValue,System.Double.MaxValue,System.Double.Epsilon + let floatSeq = iseq [0.0; 0.5; 2.0; 1.5; 1.0; minFloat;maxFloat;epsilon;-epsilon] + let resultFloat = ISeq.sortDescending floatSeq + let expectedFloat = iseq [maxFloat; 2.0; 1.5; 1.0; 0.5; epsilon; 0.0; -epsilon; minFloat; ] + VerifySeqsEqual expectedFloat resultFloat + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.sort null |> ignore) + () + + [] + member this.SortByDescending() = + + // integer ISeq + let funcInt x = Math.Abs(x-5) + let resultInt = ISeq.sortByDescending funcInt (iseq [1;2;4;5;7]) + let expectedInt = iseq [1;2;7;4;5] + VerifySeqsEqual expectedInt resultInt + + // string ISeq + let funcStr (x:string) = x.IndexOf("key") + let resultStr =ISeq.sortByDescending funcStr (iseq ["st(key)r";"str(key)";"s(key)tr";"(key)str"]) + + let expectedStr = iseq ["str(key)";"st(key)r";"s(key)tr";"(key)str"] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.sortByDescending funcInt ISeq.empty + VerifySeqsEqual resultEpt ISeq.empty + + // tuple ISeq + let tupSeq = (iseq[(2,"a");(1,"d");(1,"b");(1,"a");(2,"x");(2,"b");(1,"x")]) + let resultTup = ISeq.sortByDescending snd tupSeq + let expectedTup = (iseq[(2,"x");(1,"x");(1,"d");(1,"b");(2,"b");(2,"a");(1,"a")]) + VerifySeqsEqual expectedTup resultTup + + // float ISeq + let minFloat,maxFloat,epsilon = System.Double.MinValue,System.Double.MaxValue,System.Double.Epsilon + let floatSeq = iseq [0.0; 0.5; 2.0; 1.5; 1.0; minFloat;maxFloat;epsilon;-epsilon] + let resultFloat = ISeq.sortByDescending id floatSeq + let expectedFloat = iseq [maxFloat; 2.0; 1.5; 1.0; 0.5; epsilon; 0.0; -epsilon; minFloat; ] + VerifySeqsEqual expectedFloat resultFloat + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.sortByDescending funcInt null |> ignore) + () + + member this.SortWith() = + + // integer ISeq + let intComparer a b = compare (a%3) (b%3) + let resultInt = ISeq.sortWith intComparer (iseq <| seq {0..10}) + let expectedInt = iseq [0;3;6;9;1;4;7;10;2;5;8] + VerifySeqsEqual expectedInt resultInt + + // string ISeq + let resultStr = ISeq.sortWith compare (iseq ["str1";"str3";"str2";"str4"]) + let expectedStr = iseq ["str1";"str2";"str3";"str4"] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.sortWith intComparer ISeq.empty + VerifySeqsEqual resultEpt ISeq.empty + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.sortWith intComparer null |> ignore) + + () + + [] + member this.Sum() = + + // integer ISeq + let resultInt = ISeq.sum (iseq [1..10]) + Assert.AreEqual(55,resultInt) + + // float32 ISeq + let floatSeq = (iseq [ 1.2f;3.5f;6.7f ]) + let resultFloat = ISeq.sum floatSeq + if resultFloat <> 11.4f then Assert.Fail() + + // double ISeq + let doubleSeq = (iseq [ 1.0;8.0 ]) + let resultDouble = ISeq.sum doubleSeq + if resultDouble <> 9.0 then Assert.Fail() + + // decimal ISeq + let decimalSeq = (iseq [ 0M;19M;19.03M ]) + let resultDecimal = ISeq.sum decimalSeq + if resultDecimal <> 38.03M then Assert.Fail() + + + // empty float32 ISeq + let emptyFloatSeq = ISeq.empty + let resultEptFloat = ISeq.sum emptyFloatSeq + if resultEptFloat <> 0.0f then Assert.Fail() + + // empty double ISeq + let emptyDoubleSeq = ISeq.empty + let resultDouEmp = ISeq.sum emptyDoubleSeq + if resultDouEmp <> 0.0 then Assert.Fail() + + // empty decimal ISeq + let emptyDecimalSeq = ISeq.empty + let resultDecEmp = ISeq.sum emptyDecimalSeq + if resultDecEmp <> 0M then Assert.Fail() + + () + + [] + member this.SumBy() = + + // integer ISeq + let resultInt = ISeq.sumBy int (iseq [1..10]) + Assert.AreEqual(55,resultInt) + + // float32 ISeq + let floatSeq = (iseq [ 1.2f;3.5f;6.7f ]) + let resultFloat = ISeq.sumBy float32 floatSeq + if resultFloat <> 11.4f then Assert.Fail() + + // double ISeq + let doubleSeq = (iseq [ 1.0;8.0 ]) + let resultDouble = ISeq.sumBy double doubleSeq + if resultDouble <> 9.0 then Assert.Fail() + + // decimal ISeq + let decimalSeq = (iseq [ 0M;19M;19.03M ]) + let resultDecimal = ISeq.sumBy decimal decimalSeq + if resultDecimal <> 38.03M then Assert.Fail() + + // empty float32 ISeq + let emptyFloatSeq = ISeq.empty + let resultEptFloat = ISeq.sumBy float32 emptyFloatSeq + if resultEptFloat <> 0.0f then Assert.Fail() + + // empty double ISeq + let emptyDoubleSeq = ISeq.empty + let resultDouEmp = ISeq.sumBy double emptyDoubleSeq + if resultDouEmp <> 0.0 then Assert.Fail() + + // empty decimal ISeq + let emptyDecimalSeq = ISeq.empty + let resultDecEmp = ISeq.sumBy decimal emptyDecimalSeq + if resultDecEmp <> 0M then Assert.Fail() + + () + + [] + member this.Take() = + // integer ISeq + + let resultInt = ISeq.take 3 (iseq [1;2;4;5;7]) + + let expectedInt = iseq [1;2;4] + VerifySeqsEqual expectedInt resultInt + + // string ISeq + + let resultStr =ISeq.take 2(iseq ["str1";"str2";"str3";"str4"]) + + let expectedStr = iseq ["str1";"str2"] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.take 0 ISeq.empty + + VerifySeqsEqual resultEpt ISeq.empty + + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.take 1 null |> ignore) + () + + [] + member this.takeWhile() = + // integer ISeq + let funcInt x = (x < 6) + let resultInt = ISeq.takeWhile funcInt (iseq [1;2;4;5;6;7]) + + let expectedInt = iseq [1;2;4;5] + VerifySeqsEqual expectedInt resultInt + + // string ISeq + let funcStr (x:string) = (x.Length < 4) + let resultStr =ISeq.takeWhile funcStr (iseq ["a"; "ab"; "abc"; "abcd"; "abcde"]) + + let expectedStr = iseq ["a"; "ab"; "abc"] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.takeWhile funcInt ISeq.empty + VerifySeqsEqual resultEpt ISeq.empty + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.takeWhile funcInt null |> ignore) + () + + [] + member this.ToArray() = + // integer ISeq + let resultInt = ISeq.toArray(iseq [1;2;4;5;7]) + + let expectedInt = [|1;2;4;5;7|] + Assert.AreEqual(expectedInt,resultInt) + + // string ISeq + let resultStr =ISeq.toArray (iseq ["str1";"str2";"str3"]) + + let expectedStr = [|"str1";"str2";"str3"|] + Assert.AreEqual(expectedStr,resultStr) + + // empty ISeq + let resultEpt = ISeq.toArray ISeq.empty + Assert.AreEqual([||],resultEpt) + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.toArray null |> ignore) + () + + [] + member this.ToArrayFromICollection() = + let inputCollection = ResizeArray(iseq [1;2;4;5;7]) + let resultInt = ISeq.toArray((iseq inputCollection)) + let expectedInt = [|1;2;4;5;7|] + Assert.AreEqual(expectedInt,resultInt) + + [] + member this.ToArrayEmptyInput() = + let resultInt = ISeq.toArray(ISeq.empty) + let expectedInt = Array.empty + Assert.AreEqual(expectedInt,resultInt) + + [] + member this.ToArrayFromArray() = + let resultInt = ISeq.toArray((iseq [|1;2;4;5;7|])) + let expectedInt = [|1;2;4;5;7|] + Assert.AreEqual(expectedInt,resultInt) + + [] + member this.ToArrayFromList() = + let resultInt = ISeq.toArray((iseq [1;2;4;5;7])) + let expectedInt = [|1;2;4;5;7|] + Assert.AreEqual(expectedInt,resultInt) + + [] + member this.ToList() = + // integer ISeq + let resultInt = ISeq.toList (iseq [1;2;4;5;7]) + let expectedInt = [1;2;4;5;7] + Assert.AreEqual(expectedInt,resultInt) + + // string ISeq + let resultStr =ISeq.toList (iseq ["str1";"str2";"str3"]) + let expectedStr = ["str1";"str2";"str3"] + Assert.AreEqual(expectedStr,resultStr) + + // empty ISeq + let resultEpt = ISeq.toList ISeq.empty + Assert.AreEqual([],resultEpt) + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.toList null |> ignore) + () + + [] + member this.Truncate() = + // integer ISeq + let resultInt = ISeq.truncate 3 (iseq [1;2;4;5;7]) + let expectedInt = [1;2;4] + VerifySeqsEqual expectedInt resultInt + + // string ISeq + let resultStr =ISeq.truncate 2 (iseq ["str1";"str2";"str3"]) + let expectedStr = ["str1";"str2"] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.truncate 0 ISeq.empty + VerifySeqsEqual ISeq.empty resultEpt + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.truncate 1 null |> ignore) + + // negative count + VerifySeqsEqual ISeq.empty <| ISeq.truncate -1 (iseq [1;2;4;5;7]) + VerifySeqsEqual ISeq.empty <| ISeq.truncate System.Int32.MinValue (iseq [1;2;4;5;7]) + + () + + [] + member this.tryFind() = + // integer ISeq + let resultInt = ISeq.tryFind (fun x -> (x%2=0)) (iseq [1;2;4;5;7]) + Assert.AreEqual(Some(2), resultInt) + + // integer ISeq - None + let resultInt = ISeq.tryFind (fun x -> (x%2=0)) (iseq [1;3;5;7]) + Assert.AreEqual(None, resultInt) + + // string ISeq + let resultStr = ISeq.tryFind (fun (x:string) -> x.Contains("2")) (iseq ["str1";"str2";"str3"]) + Assert.AreEqual(Some("str2"),resultStr) + + // string ISeq - None + let resultStr = ISeq.tryFind (fun (x:string) -> x.Contains("2")) (iseq ["str1";"str4";"str3"]) + Assert.AreEqual(None,resultStr) + + + // empty ISeq + let resultEpt = ISeq.tryFind (fun x -> (x%2=0)) ISeq.empty + Assert.AreEqual(None,resultEpt) + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.tryFind (fun x -> (x%2=0)) null |> ignore) + () + + [] + member this.TryFindBack() = + // integer ISeq + let resultInt = ISeq.tryFindBack (fun x -> (x%2=0)) (iseq [1;2;4;5;7]) + Assert.AreEqual(Some 4, resultInt) + + // integer ISeq - None + let resultInt = ISeq.tryFindBack (fun x -> (x%2=0)) (iseq [1;3;5;7]) + Assert.AreEqual(None, resultInt) + + // string ISeq + let resultStr = ISeq.tryFindBack (fun (x:string) -> x.Contains("2")) (iseq ["str1";"str2";"str2x";"str3"]) + Assert.AreEqual(Some "str2x", resultStr) + + // string ISeq - None + let resultStr = ISeq.tryFindBack (fun (x:string) -> x.Contains("2")) (iseq ["str1";"str4";"str3"]) + Assert.AreEqual(None, resultStr) + + // empty ISeq + let resultEpt = ISeq.tryFindBack (fun x -> (x%2=0)) ISeq.empty + Assert.AreEqual(None, resultEpt) + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.tryFindBack (fun x -> (x%2=0)) null |> ignore) + () + + [] + member this.TryFindIndex() = + + // integer ISeq + let resultInt = ISeq.tryFindIndex (fun x -> (x % 5 = 0)) (iseq [8; 9; 10]) + Assert.AreEqual(Some(2), resultInt) + + // integer ISeq - None + let resultInt = ISeq.tryFindIndex (fun x -> (x % 5 = 0)) (iseq [9;3;11]) + Assert.AreEqual(None, resultInt) + + // string ISeq + let resultStr = ISeq.tryFindIndex (fun (x:string) -> x.Contains("2")) (iseq ["str1"; "str2"; "str3"]) + Assert.AreEqual(Some(1),resultStr) + + // string ISeq - None + let resultStr = ISeq.tryFindIndex (fun (x:string) -> x.Contains("2")) (iseq ["str1"; "str4"; "str3"]) + Assert.AreEqual(None,resultStr) + + + // empty ISeq + let resultEpt = ISeq.tryFindIndex (fun x -> (x%2=0)) ISeq.empty + Assert.AreEqual(None, resultEpt) + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.tryFindIndex (fun x -> (x % 2 = 0)) null |> ignore) + () + + [] + member this.TryFindIndexBack() = + + // integer ISeq + let resultInt = ISeq.tryFindIndexBack (fun x -> (x % 5 = 0)) (iseq [5; 9; 10; 12]) + Assert.AreEqual(Some(2), resultInt) + + // integer ISeq - None + let resultInt = ISeq.tryFindIndexBack (fun x -> (x % 5 = 0)) (iseq [9;3;11]) + Assert.AreEqual(None, resultInt) + + // string ISeq + let resultStr = ISeq.tryFindIndexBack (fun (x:string) -> x.Contains("2")) (iseq ["str1"; "str2"; "str2x"; "str3"]) + Assert.AreEqual(Some(2), resultStr) + + // string ISeq - None + let resultStr = ISeq.tryFindIndexBack (fun (x:string) -> x.Contains("2")) (iseq ["str1"; "str4"; "str3"]) + Assert.AreEqual(None, resultStr) + + // empty ISeq + let resultEpt = ISeq.tryFindIndexBack (fun x -> (x%2=0)) ISeq.empty + Assert.AreEqual(None, resultEpt) + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.tryFindIndexBack (fun x -> (x % 2 = 0)) null |> ignore) + () + + [] + member this.Unfold() = + // integer ISeq + + let resultInt = ISeq.unfold (fun x -> if x = 1 then Some(7,2) else None) 1 + + VerifySeqsEqual (iseq [7]) resultInt + + // string ISeq + let resultStr =ISeq.unfold (fun (x:string) -> if x.Contains("unfold") then Some("a","b") else None) "unfold" + VerifySeqsEqual (iseq ["a"]) resultStr + () + + + [] + member this.Windowed() = + + let testWindowed config = + try + config.InputSeq + |> ISeq.windowed config.WindowSize + |> VerifySeqsEqual config.ExpectedSeq + with + | _ when Option.isNone config.Exception -> Assert.Fail() + | e when e.GetType() = (Option.get config.Exception) -> () + | _ -> Assert.Fail() + + { + InputSeq = iseq [1..10] + WindowSize = 1 + ExpectedSeq = iseq <| seq { for i in 1..10 do yield [| i |] } + Exception = None + } |> testWindowed + { + InputSeq = iseq [1..10] + WindowSize = 5 + ExpectedSeq = iseq <| seq { for i in 1..6 do yield [| i; i+1; i+2; i+3; i+4 |] } + Exception = None + } |> testWindowed + { + InputSeq = iseq [1..10] + WindowSize = 10 + ExpectedSeq = iseq <| seq { yield [| 1 .. 10 |] } + Exception = None + } |> testWindowed + { + InputSeq = iseq [1..10] + WindowSize = 25 + ExpectedSeq = ISeq.empty + Exception = None + } |> testWindowed + { + InputSeq = iseq ["str1";"str2";"str3";"str4"] + WindowSize = 2 + ExpectedSeq = iseq [ [|"str1";"str2"|];[|"str2";"str3"|];[|"str3";"str4"|]] + Exception = None + } |> testWindowed + { + InputSeq = ISeq.empty + WindowSize = 2 + ExpectedSeq = ISeq.empty + Exception = None + } |> testWindowed + //{ + // InputSeq = null + // WindowSize = 2 + // ExpectedSeq = ISeq.empty + // Exception = Some typeof + //} |> testWindowed + { + InputSeq = iseq [1..10] + WindowSize = 0 + ExpectedSeq = ISeq.empty + Exception = Some typeof + } |> testWindowed + + () + + [] + member this.Zip() = + + // integer ISeq + let resultInt = ISeq.zip (iseq [1..7]) (iseq [11..17]) + let expectedInt = + iseq <| seq { for i in 1..7 do + yield i, i+10 } + VerifySeqsEqual expectedInt resultInt + + // string ISeq + let resultStr =ISeq.zip (iseq ["str3";"str4"]) (iseq ["str1";"str2"]) + let expectedStr = iseq ["str3","str1";"str4","str2"] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.zip ISeq.empty ISeq.empty + VerifySeqsEqual ISeq.empty resultEpt + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.zip null null |> ignore) + //CheckThrowsArgumentNullException(fun() -> ISeq.zip null (iseq [1..7]) |> ignore) + //CheckThrowsArgumentNullException(fun() -> ISeq.zip (iseq [1..7]) null |> ignore) + () + + [] + member this.Zip3() = + // integer ISeq + let resultInt = ISeq.zip3 (iseq [1..7]) (iseq [11..17]) (iseq [21..27]) + let expectedInt = + iseq <| seq { for i in 1..7 do + yield i, (i + 10), (i + 20) } + VerifySeqsEqual expectedInt resultInt + + // string ISeq + let resultStr =ISeq.zip3 (iseq ["str1";"str2"]) (iseq ["str11";"str12"]) (iseq ["str21";"str22"]) + let expectedStr = iseq ["str1","str11","str21";"str2","str12","str22" ] + VerifySeqsEqual expectedStr resultStr + + // empty ISeq + let resultEpt = ISeq.zip3 ISeq.empty ISeq.empty ISeq.empty + VerifySeqsEqual ISeq.empty resultEpt + + //// null ISeq + //CheckThrowsArgumentNullException(fun() -> ISeq.zip3 null null null |> ignore) + //CheckThrowsArgumentNullException(fun() -> ISeq.zip3 null (iseq [1..7]) (iseq [1..7]) |> ignore) + //CheckThrowsArgumentNullException(fun() -> ISeq.zip3 (iseq [1..7]) null (iseq [1..7]) |> ignore) + //CheckThrowsArgumentNullException(fun() -> ISeq.zip3 (iseq [1..7]) (iseq [1..7]) null |> ignore) + () + + [] + member this.tryPick() = + // integer ISeq + let resultInt = ISeq.tryPick (fun x-> if x = 1 then Some("got") else None) (iseq [1..5]) + + Assert.AreEqual(Some("got"),resultInt) + + // string ISeq + let resultStr = ISeq.tryPick (fun x-> if x = "Are" then Some("got") else None) (iseq ["Lists"; "Are"]) + Assert.AreEqual(Some("got"),resultStr) + + // empty ISeq + let resultEpt = ISeq.tryPick (fun x-> if x = 1 then Some("got") else None) ISeq.empty + Assert.IsNull(resultEpt) + + //// null ISeq + //let nullSeq : iseq<'a> = null + //let funcNull x = Some(1) + + //CheckThrowsArgumentNullException(fun () -> ISeq.tryPick funcNull nullSeq |> ignore) + + () + + [] + member this.tryItem() = + // integer ISeq + let resultInt = ISeq.tryItem 3 (iseq { 10..20 }) + Assert.AreEqual(Some(13), resultInt) + + // string ISeq + let resultStr = ISeq.tryItem 2 (iseq ["Lists"; "Are"; "Cool"; "List" ]) + Assert.AreEqual(Some("Cool"), resultStr) + + // empty ISeq + let resultEmpty = ISeq.tryItem 0 ISeq.empty + Assert.AreEqual(None, resultEmpty) + + //// null ISeq + //let nullSeq:iseq<'a> = null + //CheckThrowsArgumentNullException (fun () -> ISeq.tryItem 3 nullSeq |> ignore) + + // Negative index + let resultNegativeIndex = ISeq.tryItem -1 (iseq { 10..20 }) + Assert.AreEqual(None, resultNegativeIndex) + + // Index greater than length + let resultIndexGreater = ISeq.tryItem 31 (iseq { 10..20 }) + Assert.AreEqual(None, resultIndexGreater) diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ISeqProperties.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ISeqProperties.fs new file mode 100644 index 00000000000..d37172bf0b9 --- /dev/null +++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ISeqProperties.fs @@ -0,0 +1,39 @@ +// 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. + +module FSharp.Core.Unittests.FSharp_Core.Microsoft_FSharp_Collections.ISeqProperties + +open System +open System.Collections.Generic +open NUnit.Framework +open FsCheck +open Utils + +let sortByStable<'a when 'a : comparison> (xs : 'a []) = + let indexed = xs|> ISeq.ofSeq |> ISeq.indexed + let sorted = indexed |> ISeq.sortBy snd + isStable sorted + +[] +let ``ISeq.sortBy is stable`` () = + Check.QuickThrowOnFailure sortByStable + Check.QuickThrowOnFailure sortByStable + +let sortWithStable<'a when 'a : comparison> (xs : 'a []) = + let indexed = xs |> ISeq.ofSeq |> ISeq.indexed |> Seq.toList + let sorted = indexed |> ISeq.ofSeq |> ISeq.sortWith (fun x y -> compare (snd x) (snd y)) + isStable sorted + +[] +let ``ISeq.sortWithStable is stable`` () = + Check.QuickThrowOnFailure sortWithStable + Check.QuickThrowOnFailure sortWithStable + +let distinctByStable<'a when 'a : comparison> (xs : 'a []) = + let indexed = xs|> ISeq.ofSeq |> ISeq.indexed + let sorted = indexed |> ISeq.distinctBy snd + isStable sorted + +[] +let ``ISeq.distinctBy is stable`` () = + Check.QuickThrowOnFailure distinctByStable + Check.QuickThrowOnFailure distinctByStable diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.coreclr.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.coreclr.fs index cd7c9087a50..a6dca4658b8 100644 --- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.coreclr.fs +++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.coreclr.fs @@ -293,6 +293,193 @@ Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityC Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] Structural[T]() Microsoft.FSharp.Collections.HashIdentity: System.String ToString() Microsoft.FSharp.Collections.HashIdentity: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Int32 HaltedIdx +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Int32 get_HaltedIdx() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: TResult Result +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: TResult get_Result() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: TState State +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void .ctor(TResult, TState) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void ChainDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void OnDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void set_Result(TResult) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Int32 HaltedIdx +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Int32 get_HaltedIdx() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: TResult Result +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: TResult get_Result() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: TState State +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Void .ctor(TResult, TState) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Void ChainDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Void set_Result(TResult) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: TState State +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Void .ctor(Microsoft.FSharp.Collections.SeqComposition.Activity, TState) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Void ChainDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Void OnDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: TState State +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Void .ctor(Microsoft.FSharp.Collections.SeqComposition.Activity, TState) +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Void ChainDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: Void .ctor(a) +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: a _1 +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: Void .ctor(a, b) +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: a _1 +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: b _2 +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: Void .ctor(a, b, c) +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: a _1 +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: b _2 +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: c _3 +Microsoft.FSharp.Collections.ISeqModule+Core: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c] +Microsoft.FSharp.Collections.ISeqModule+Core: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule: Boolean Contains[T](T, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule: Boolean Exists2[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,System.Boolean]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Boolean ForAll2[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,System.Boolean]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Boolean IsEmpty[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule: Int32 Length[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.ISeqModule+Core +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[System.Int32,a]] Indexed[a](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[a]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[T,T]] Pairwise[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[T1,T2]] AllPairs[T1,T2](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T1], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T2]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[T1,T2]] Zip[T1,T2](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T1], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T2]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[TKey,Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]]] GroupByRef[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[TKey,Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]]] GroupByVal[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[TKey,System.Int32]] CountByRef[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[TKey,System.Int32]] CountByVal[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`3[T1,T2,T3]] Zip3[T1,T2,T3](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T1], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T2], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T3]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult] Collect[T,TCollection,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TCollection], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TState] ScanBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], TState) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TState] Scan[TState,T](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T[]] ChunkBySize[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T[]] SplitInto[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T[]] Windowed[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Append[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Cache[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Cast[T](System.Collections.IEnumerable) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Concat[TCollection,T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TCollection]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Delay[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] DistinctBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Distinct[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Empty[T]() +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Except[T](System.Collections.Generic.IEnumerable`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] InitializeInfinite[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] OfArray[T](T[]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] OfResizeArrayUnchecked[T](System.Collections.Generic.List`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] OfSeq[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Permute[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Replicate[T](Int32, T) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Reverse[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Singleton[T](T) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] SkipWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Skip[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] SortByDescending[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] SortBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] SortDescending[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] SortWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Sort[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Tail[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] TakeWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Take[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Truncate[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Unfold[TState,T](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[T,TState]]], TState) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[V] Map2[T,TResult,V](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,V]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[V] MapIndexed2[T,TResult,V](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,V]]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[W] Map3[T,TResult,V,W](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[V,W]]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[V]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[b] Choose[a,b](Microsoft.FSharp.Core.FSharpFunc`2[a,Microsoft.FSharp.Core.FSharpOption`1[b]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[a]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[b] MapIndexed[a,b](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[a,b]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[a]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryHead[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryItem[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryLast[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule: System.Tuple`2[Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult],TState] MapFoldBack[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,System.Tuple`2[TResult,TState]]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], TState) +Microsoft.FSharp.Collections.ISeqModule: System.Tuple`2[Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult],TState] MapFold[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Tuple`2[TResult,TState]]], TState, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule: T Average[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T ExactlyOne[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T FindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Find[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Head[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Item[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Last[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T MaxBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Max[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T MinBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Min[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T ReduceBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Reduce[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Sum[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: TResult AverageBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: TResult Pick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: TResult SumBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: TState Fold2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TState]]], TState, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T1], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T2]) +Microsoft.FSharp.Collections.ISeqModule: TState FoldBack2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T1], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T2], TState) +Microsoft.FSharp.Collections.ISeqModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], TState) +Microsoft.FSharp.Collections.ISeqModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T[] ToArray[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Void Iterate2[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Void IterateIndexed2[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.Unit]]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) Microsoft.FSharp.Collections.ListModule: Boolean Contains[T](T, Microsoft.FSharp.Collections.FSharpList`1[T]) Microsoft.FSharp.Collections.ListModule: Boolean Equals(System.Object) Microsoft.FSharp.Collections.ListModule: Boolean Exists2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) @@ -425,6 +612,55 @@ Microsoft.FSharp.Collections.MapModule: TResult Pick[TKey,T,TResult](Microsoft.F Microsoft.FSharp.Collections.MapModule: TState FoldBack[TKey,T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T], TState) Microsoft.FSharp.Collections.MapModule: TState Fold[TKey,T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]]], TState, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) Microsoft.FSharp.Collections.MapModule: Void Iterate[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.SeqComposition.Activity: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Activity: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Activity: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Activity: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Activity: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.SeqComposition.Activity: Void ChainDispose() +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Void .ctor() +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Void ChainDispose() +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Void .ctor() +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Void ChainDispose() +Microsoft.FSharp.Collections.SeqComposition.Core+NoValue: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Core+NoValue: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Core+NoValue: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Core+NoValue: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Core: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Core: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Core: Microsoft.FSharp.Collections.SeqComposition.Core+NoValue +Microsoft.FSharp.Collections.SeqComposition.Core: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Core: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Int32 HaltedIdx +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Int32 get_HaltedIdx() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: TResult Result +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: TResult get_Result() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Void .ctor(TResult) +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Void ChainDispose() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Void set_Result(TResult) +Microsoft.FSharp.Collections.SeqComposition.IOutOfBand: Void ListenForStopFurtherProcessing(System.Action`1[System.Int32]) +Microsoft.FSharp.Collections.SeqComposition.IOutOfBand: Void StopFurtherProcessing(Int32) +Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult] PushTransform[TResult](Microsoft.FSharp.Collections.SeqComposition.ITransformFactory`2[T,TResult]) +Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]: TResult Fold[TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]]) +Microsoft.FSharp.Collections.SeqComposition.ITransformFactory`2[T,TResult]: Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,V] Compose[V](Microsoft.FSharp.Collections.SeqComposition.IOutOfBand, Int32, Microsoft.FSharp.Collections.SeqComposition.Activity`2[TResult,V]) Microsoft.FSharp.Collections.SeqModule: Boolean Contains[T](T, System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Boolean Equals(System.Object) Microsoft.FSharp.Collections.SeqModule: Boolean Exists2[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]) @@ -882,7 +1118,10 @@ Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Boolean Equal Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Boolean get_CheckClose() Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Int32 GenerateNext(System.Collections.Generic.IEnumerable`1[T] ByRef) Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Int32 GetHashCode() +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Int32 Length() +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Append(Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: System.Collections.Generic.IEnumerator`1[T] GetFreshEnumerator() +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: System.Collections.Generic.IEnumerable`1[T] GetRaw() Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: System.String ToString() Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: System.Type GetType() Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: T LastGenerated diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs index 0fdcc27abea..b1f492245e1 100644 --- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs +++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs @@ -280,6 +280,193 @@ Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityC Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] Structural[T]() Microsoft.FSharp.Collections.HashIdentity: System.String ToString() Microsoft.FSharp.Collections.HashIdentity: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Int32 HaltedIdx +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Int32 get_HaltedIdx() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: TResult Result +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: TResult get_Result() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: TState State +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void .ctor(TResult, TState) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void ChainDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void OnDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void set_Result(TResult) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Int32 HaltedIdx +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Int32 get_HaltedIdx() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: TResult Result +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: TResult get_Result() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: TState State +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Void .ctor(TResult, TState) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Void ChainDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Void set_Result(TResult) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: TState State +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Void .ctor(Microsoft.FSharp.Collections.SeqComposition.Activity, TState) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Void ChainDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Void OnDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: TState State +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Void .ctor(Microsoft.FSharp.Collections.SeqComposition.Activity, TState) +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Void ChainDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: Void .ctor(a) +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: a _1 +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: Void .ctor(a, b) +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: a _1 +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: b _2 +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: Void .ctor(a, b, c) +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: a _1 +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: b _2 +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: c _3 +Microsoft.FSharp.Collections.ISeqModule+Core: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c] +Microsoft.FSharp.Collections.ISeqModule+Core: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule: Boolean Contains[T](T, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule: Boolean Exists2[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,System.Boolean]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Boolean ForAll2[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,System.Boolean]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Boolean IsEmpty[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule: Int32 Length[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.ISeqModule+Core +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[System.Int32,a]] Indexed[a](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[a]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[T,T]] Pairwise[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[T1,T2]] AllPairs[T1,T2](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T1], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T2]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[T1,T2]] Zip[T1,T2](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T1], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T2]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[TKey,Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]]] GroupByRef[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[TKey,Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]]] GroupByVal[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[TKey,System.Int32]] CountByRef[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[TKey,System.Int32]] CountByVal[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`3[T1,T2,T3]] Zip3[T1,T2,T3](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T1], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T2], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T3]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult] Collect[T,TCollection,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TCollection], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TState] ScanBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], TState) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TState] Scan[TState,T](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T[]] ChunkBySize[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T[]] SplitInto[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T[]] Windowed[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Append[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Cache[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Cast[T](System.Collections.IEnumerable) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Concat[TCollection,T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TCollection]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Delay[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] DistinctBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Distinct[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Empty[T]() +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Except[T](System.Collections.Generic.IEnumerable`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] InitializeInfinite[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] OfArray[T](T[]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] OfResizeArrayUnchecked[T](System.Collections.Generic.List`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] OfSeq[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Permute[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Replicate[T](Int32, T) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Reverse[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Singleton[T](T) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] SkipWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Skip[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] SortByDescending[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] SortBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] SortDescending[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] SortWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Sort[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Tail[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] TakeWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Take[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Truncate[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Unfold[TState,T](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[T,TState]]], TState) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[V] Map2[T,TResult,V](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,V]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[V] MapIndexed2[T,TResult,V](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,V]]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[W] Map3[T,TResult,V,W](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[V,W]]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[V]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[b] Choose[a,b](Microsoft.FSharp.Core.FSharpFunc`2[a,Microsoft.FSharp.Core.FSharpOption`1[b]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[a]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[b] MapIndexed[a,b](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[a,b]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[a]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryHead[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryItem[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryLast[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule: System.Tuple`2[Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult],TState] MapFoldBack[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,System.Tuple`2[TResult,TState]]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], TState) +Microsoft.FSharp.Collections.ISeqModule: System.Tuple`2[Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult],TState] MapFold[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Tuple`2[TResult,TState]]], TState, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule: T Average[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T ExactlyOne[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T FindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Find[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Head[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Item[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Last[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T MaxBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Max[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T MinBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Min[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T ReduceBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Reduce[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Sum[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: TResult AverageBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: TResult Pick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: TResult SumBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: TState Fold2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TState]]], TState, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T1], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T2]) +Microsoft.FSharp.Collections.ISeqModule: TState FoldBack2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T1], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T2], TState) +Microsoft.FSharp.Collections.ISeqModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], TState) +Microsoft.FSharp.Collections.ISeqModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T[] ToArray[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Void Iterate2[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Void IterateIndexed2[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.Unit]]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) Microsoft.FSharp.Collections.ListModule: Boolean Contains[T](T, Microsoft.FSharp.Collections.FSharpList`1[T]) Microsoft.FSharp.Collections.ListModule: Boolean Equals(System.Object) Microsoft.FSharp.Collections.ListModule: Boolean Exists2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) @@ -412,6 +599,55 @@ Microsoft.FSharp.Collections.MapModule: TResult Pick[TKey,T,TResult](Microsoft.F Microsoft.FSharp.Collections.MapModule: TState FoldBack[TKey,T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T], TState) Microsoft.FSharp.Collections.MapModule: TState Fold[TKey,T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]]], TState, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) Microsoft.FSharp.Collections.MapModule: Void Iterate[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.SeqComposition.Activity: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Activity: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Activity: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Activity: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Activity: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.SeqComposition.Activity: Void ChainDispose() +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Void .ctor() +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Void ChainDispose() +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Void .ctor() +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Void ChainDispose() +Microsoft.FSharp.Collections.SeqComposition.Core+NoValue: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Core+NoValue: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Core+NoValue: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Core+NoValue: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Core: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Core: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Core: Microsoft.FSharp.Collections.SeqComposition.Core+NoValue +Microsoft.FSharp.Collections.SeqComposition.Core: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Core: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Int32 HaltedIdx +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Int32 get_HaltedIdx() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: TResult Result +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: TResult get_Result() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Void .ctor(TResult) +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Void ChainDispose() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Void set_Result(TResult) +Microsoft.FSharp.Collections.SeqComposition.IOutOfBand: Void ListenForStopFurtherProcessing(System.Action`1[System.Int32]) +Microsoft.FSharp.Collections.SeqComposition.IOutOfBand: Void StopFurtherProcessing(Int32) +Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult] PushTransform[TResult](Microsoft.FSharp.Collections.SeqComposition.ITransformFactory`2[T,TResult]) +Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]: TResult Fold[TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]]) +Microsoft.FSharp.Collections.SeqComposition.ITransformFactory`2[T,TResult]: Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,V] Compose[V](Microsoft.FSharp.Collections.SeqComposition.IOutOfBand, Int32, Microsoft.FSharp.Collections.SeqComposition.Activity`2[TResult,V]) Microsoft.FSharp.Collections.SeqModule: Boolean Contains[T](T, System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Boolean Equals(System.Object) Microsoft.FSharp.Collections.SeqModule: Boolean Exists2[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]) @@ -916,7 +1152,10 @@ Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Boolean Equal Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Boolean get_CheckClose() Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Int32 GenerateNext(System.Collections.Generic.IEnumerable`1[T] ByRef) Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Int32 GetHashCode() +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Int32 Length() +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Append(Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: System.Collections.Generic.IEnumerator`1[T] GetFreshEnumerator() +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: System.Collections.Generic.IEnumerable`1[T] GetRaw() Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: System.String ToString() Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: System.Type GetType() Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: T LastGenerated diff --git a/src/fsharp/FSharp.Core/FSharp.Core.fsproj b/src/fsharp/FSharp.Core/FSharp.Core.fsproj index ee0bd8f50ef..7ca7782f4a4 100644 --- a/src/fsharp/FSharp.Core/FSharp.Core.fsproj +++ b/src/fsharp/FSharp.Core/FSharp.Core.fsproj @@ -94,12 +94,30 @@ Collections/collections.fs + + Collections/list.fsi + + + Collections/list.fs + + + Collections/array.fsi + + + Collections/array.fs + Collections/seqcore.fsi Collections/seqcore.fs + + Collections/iseq.fsi + + + Collections/iseq.fs + Collections/seq.fsi @@ -112,18 +130,6 @@ Collections/string.fs - - Collections/list.fsi - - - Collections/list.fs - - - Collections/array.fsi - - - Collections/array.fs - Collections/array3.fsi diff --git a/src/fsharp/FSharp.Core/array.fs b/src/fsharp/FSharp.Core/array.fs index 3a1cd0a94ef..c33e97b11cb 100644 --- a/src/fsharp/FSharp.Core/array.fs +++ b/src/fsharp/FSharp.Core/array.fs @@ -8,7 +8,6 @@ namespace Microsoft.FSharp.Collections open Microsoft.FSharp.Core open Microsoft.FSharp.Collections open Microsoft.FSharp.Core.Operators - open Microsoft.FSharp.Core.CompilerServices open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators #if FX_RESHAPED_REFLECTION open System.Reflection @@ -100,12 +99,22 @@ namespace Microsoft.FSharp.Collections j <- j + len res + [] + let toSeq array = + checkNonNull "array" array + Microsoft.FSharp.Primitives.Basics.Array.toSeq array + + [] + let ofSeq source = + checkNonNull "source" source + Microsoft.FSharp.Primitives.Basics.Array.ofSeq source + [] let concat (arrays: seq<'T[]>) = checkNonNull "arrays" arrays match arrays with | :? ('T[][]) as ts -> ts |> concatArrays // avoid a clone, since we only read the array - | _ -> arrays |> Seq.toArray |> concatArrays + | _ -> arrays |> ofSeq |> concatArrays [] let replicate count x = @@ -185,7 +194,7 @@ namespace Microsoft.FSharp.Collections let countByValueType (projection:'T->'Key) (array:'T[]) = countByImpl HashIdentity.Structural<'Key> projection id array // Wrap a StructBox around all keys in case the key type is itself a type using null as a representation - let countByRefType (projection:'T->'Key) (array:'T[]) = countByImpl RuntimeHelpers.StructBox<'Key>.Comparer (fun t -> RuntimeHelpers.StructBox (projection t)) (fun sb -> sb.Value) array + let countByRefType (projection:'T->'Key) (array:'T[]) = countByImpl StructBox<'Key>.Comparer (fun t -> StructBox (projection t)) (fun sb -> sb.Value) array [] let countBy (projection:'T->'Key) (array:'T[]) = @@ -435,7 +444,7 @@ namespace Microsoft.FSharp.Collections let groupByValueType (keyf:'T->'Key) (array:'T[]) = groupByImpl HashIdentity.Structural<'Key> keyf id array // 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) (array:'T[]) = groupByImpl RuntimeHelpers.StructBox<'Key>.Comparer (fun t -> RuntimeHelpers.StructBox (keyf t)) (fun sb -> sb.Value) array + let groupByRefType (keyf:'T->'Key) (array:'T[]) = groupByImpl StructBox<'Key>.Comparer (fun t -> StructBox (keyf t)) (fun sb -> sb.Value) array [] let groupBy (keyf:'T->'Key) (array:'T[]) = @@ -1054,16 +1063,6 @@ namespace Microsoft.FSharp.Collections let inline compareDescending a b = compare b a sortWith compareDescending array - [] - let toSeq array = - checkNonNull "array" array - Seq.ofArray array - - [] - let ofSeq source = - checkNonNull "source" source - Seq.toArray source - [] let findIndex f (array : _[]) = checkNonNull "array" array diff --git a/src/fsharp/FSharp.Core/collections.fs b/src/fsharp/FSharp.Core/collections.fs index 49275a4f529..46c73a8f68c 100644 --- a/src/fsharp/FSharp.Core/collections.fs +++ b/src/fsharp/FSharp.Core/collections.fs @@ -48,3 +48,12 @@ namespace Microsoft.FSharp.Collections { new IComparer<'T> with member __.Compare(x,y) = comparer.Invoke(x,y) } + [] + 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) } + diff --git a/src/fsharp/FSharp.Core/collections.fsi b/src/fsharp/FSharp.Core/collections.fsi index d81b542a319..5b04c9b32ba 100644 --- a/src/fsharp/FSharp.Core/collections.fsi +++ b/src/fsharp/FSharp.Core/collections.fsi @@ -49,4 +49,8 @@ namespace Microsoft.FSharp.Collections // inline justification: allows inlining of hash functions val inline FromFunctions<'T> : hasher:('T -> int) -> equality:('T -> 'T -> bool) -> IEqualityComparer<'T> - + [] + type internal StructBox<'T when 'T : equality> = + new : value:'T -> StructBox<'T> + member Value : 'T + static member Comparer : IEqualityComparer> diff --git a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs index a2517c16cc3..6014d10105e 100644 --- a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs +++ b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs @@ -98,7 +98,7 @@ module ExtraTopLevelOperators = let dictValueType (l:seq<'Key*'T>) = dictImpl HashIdentity.Structural<'Key> id id l // Wrap a StructBox around all keys in case the key type is itself a type using null as a representation - let dictRefType (l:seq<'Key*'T>) = dictImpl RuntimeHelpers.StructBox<'Key>.Comparer (fun k -> RuntimeHelpers.StructBox k) (fun sb -> sb.Value) l + let dictRefType (l:seq<'Key*'T>) = dictImpl StructBox<'Key>.Comparer (fun k -> StructBox k) (fun sb -> sb.Value) l [] let dict (l:seq<'Key*'T>) = diff --git a/src/fsharp/FSharp.Core/iseq.fs b/src/fsharp/FSharp.Core/iseq.fs new file mode 100644 index 00000000000..92dc11b2775 --- /dev/null +++ b/src/fsharp/FSharp.Core/iseq.fs @@ -0,0 +1,1345 @@ +// 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 + open Microsoft.FSharp.Collections.SeqComposition + open Microsoft.FSharp.Collections.SeqComposition.Core + + [] + module ISeq = + open IEnumerator + + module Core = + [] + 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 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 terminatingIdx = + this.Next.ChainComplete terminatingIdx + override this.ChainDispose () = + this.Next.ChainDispose () + + [] + 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 terminatingIdx = + this.OnComplete terminatingIdx + this.Next.ChainComplete terminatingIdx + override this.ChainDispose () = + try this.OnDispose () + finally this.Next.ChainDispose () + + [] + type FolderWithState<'T,'Result,'State> = + inherit Folder<'T,'Result> + + val mutable State : 'State + + new (initalResult,initState) = { + inherit Folder<'T,'Result>(initalResult) + State = initState + } + + [] + type FolderWithPostProcessing<'T,'Result,'State>(initResult,initState) = + inherit FolderWithState<'T,'Result,'State>(initResult,initState) + + abstract OnComplete : PipeIdx -> unit + abstract OnDispose : unit -> unit + + override this.ChainComplete terminatingIdx = + this.OnComplete terminatingIdx + override this.ChainDispose () = + this.OnDispose () + + 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 + + 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 PreferGetEnumerator<'T>() = + inherit EnumerableBase<'T>() + + abstract GetEnumerator: unit -> IEnumerator<'T> + abstract GetSeq : unit -> ISeq<'T> + + interface IEnumerable<'T> with + member this.GetEnumerator () : IEnumerator<'T> = this.GetEnumerator () + + interface ISeq<'T> with + member this.PushTransform<'U> (next:ITransformFactory<'T,'U>) : ISeq<'U> = (this.GetSeq()).PushTransform next + member this.Fold<'Result> (f:PipeIdx->Folder<'T,'Result>) : 'Result = (this.GetSeq()).Fold f + + [] + let empty<'T> = Microsoft.FSharp.Collections.SeqComposition.Core.EmptyEnumerable<'T>.Instance + + [] + let singleton<'T> (x:'T) : ISeq<'T> = upcast (new SingletonEnumerable<_>(x)) + + /// wraps a ResizeArray in the ISeq framework. Care must be taken that the underlying ResizeArray + /// is not modified whilst it can be accessed as the ISeq, so check on version is performed. + /// i.e. usually iteration on calls the enumerator provied by GetEnumerator ensure that the + /// list hasn't been modified (throwing an exception if it has), but such a check is not + /// performed in this case. If you want this funcitonality, then use the ofSeq function instead. + [] + let ofResizeArrayUnchecked (source:ResizeArray<'T>) : ISeq<'T> = + upcast (ThinResizeArrayEnumerable<'T> source) + + [] + let ofArray (source:array<'T>) : ISeq<'T> = + checkNonNull "source" source + upcast (ThinArrayEnumerable<'T> source) + + [] + let ofList (source:list<'T>) : ISeq<'T> = + upcast source + + [] + let ofSeq (source:seq<'T>) : ISeq<'T> = + match source with + | :? ISeq<'T> as seq -> seq + | :? array<'T> as array -> ofArray array + | null -> nullArg "source" + | _ -> upcast (ThinEnumerable<'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 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 :> IOutOfBand).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 _ -> + { new Folder<'T,'State>(seed) 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 :> IOutOfBand).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 (new UnfoldEnumerable<'T,'T,'State>(generator, state, IdentityFactory.Instance, 1)) + + [] + let initInfinite<'T> (f:int->'T) : ISeq<'T> = + upcast (new InitEnumerableDecider<'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 (new InitEnumerableDecider<'T>(Nullable count, f, 1)) + + [] + let inline iter f (source:ISeq<'T>) = + source.Fold (fun _ -> + { new Folder<'T,unit> (()) 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 :> IOutOfBand).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<_,_>(0,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 :> IOutOfBand).StopFurtherProcessing pipeIdx + Unchecked.defaultof<_> + override this.OnComplete _ = () + override this.OnDispose () = this.State._2.Dispose () }) + + [] + let tryHead (source:ISeq<'T>) = + source.Fold (fun pipeIdx -> + { new Folder<'T, Option<'T>> (None) with + override this.ProcessNext value = + this.Result <- Some value + (this :> IOutOfBand).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 _ -> + upcast { new FolderWithState<'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 = + checkNonNull "itemsToExclude" itemsToExclude + source.PushTransform { new ITransformFactory<'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 -> + { new Folder<'T, bool> (false) with + override this.ProcessNext value = + if f value then + this.Result <- true + (this :> IOutOfBand).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 :> IOutOfBand).StopFurtherProcessing pipeIdx + else + (this :> IOutOfBand).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 -> + { new Folder<'T, bool> (false) with + override this.ProcessNext value = + if element = value then + this.Result <- true + (this :> IOutOfBand).StopFurtherProcessing pipeIdx + Unchecked.defaultof<_> (* return value unused in Fold context *) }) + + [] + let inline forall predicate (source:ISeq<'T>) = + source.Fold (fun pipeIdx -> + { new Folder<'T, bool> (true) with + override this.ProcessNext value = + if not (predicate value) then + this.Result <- false + (this :> IOutOfBand).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 :> IOutOfBand).StopFurtherProcessing pipeIdx + else + (this :> IOutOfBand).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 ITransformFactory<'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 ITransformFactory<'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 ITransformFactory<'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 ITransformFactory<'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 ITransformFactory<'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 ITransformFactory<'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 :> IOutOfBand).StopFurtherProcessing pipeIdx + else + let c = f value this.State.Current + if c <> 0 then + this.Result <- c + (this :> IOutOfBand).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 ITransformFactory<'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 ITransformFactory<'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 ITransformFactory<'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 ITransformFactory<'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 concat (sources:ISeq<#ISeq<'T>>) : ISeq<'T> = + upcast (ThinConcatEnumerable (sources, id)) + + (* + Represents the following seq comprehension, but they don't work at this level + + seq { + let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt folder + let mutable state = initialState + yield state + for item in enumerable do + state <- f.Invoke (state, item) + yield state } + *) + type ScanEnumerator<'T,'State>(folder:'State->'T->'State, initialState:'State, enumerable:seq<'T>) = + let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt folder + + let mutable state = 0 (*Pre-start*) + let mutable enumerator = Unchecked.defaultof> + let mutable current = initialState + + interface IEnumerator<'State> with + member this.Current: 'State = + match state with + | 0(*PreStart*) -> notStarted() + | 1(*GetEnumerator*) -> current + | 2(*MoveNext*) -> current + | _(*Finished*) -> alreadyFinished() + + interface IEnumerator with + member this.Current : obj = + box (this:>IEnumerator<'State>).Current + + member this.MoveNext () : bool = + match state with + | 0(*PreStart*) -> + state <- 1(*GetEnumerator*) + true + | 1(*GetEnumerator*) -> + enumerator <- enumerable.GetEnumerator () + state <- 2(*MoveNext*) + (this:>IEnumerator).MoveNext () + | 2(*MoveNext*) -> + if enumerator.MoveNext () then + current <- f.Invoke (current, enumerator.Current) + true + else + current <- Unchecked.defaultof<_> + state <- 3(*Finished*) + false + | _(*Finished*) -> alreadyFinished() + + member this.Reset () : unit = noReset () + + interface IDisposable with + member this.Dispose(): unit = + if isNotNull enumerator then + enumerator.Dispose () + + [] + let scan (folder:'State->'T->'State) (initialState:'State) (source:ISeq<'T>) : ISeq<'State> = + upcast { new PreferGetEnumerator<'State>() with + member this.GetEnumerator () = + upcast new ScanEnumerator<'T,'State>(folder, initialState, source) + + member this.GetSeq () = + let head = singleton initialState + let tail = + source.PushTransform { new ITransformFactory<'T,'State> with + override __.Compose _ _ next = + let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt folder + upcast { new Transform<'T,'V,'State>(next, initialState) with + override this.ProcessNext (input:'T) : bool = + this.State <- f.Invoke (this.State, input) + TailCall.avoid (next.ProcessNext this.State) } } + concat (ofList [ head ; tail ]) } + + [] + let skip (skipCount:int) (source:ISeq<'T>) : ISeq<'T> = + source.PushTransform { new ITransformFactory<'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 ITransformFactory<'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 _ -> + { new Folder<'T,'T> (LanguagePrimitives.GenericZero) 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 _ -> + { new Folder<'T,'U> (LanguagePrimitives.GenericZero<'U>) 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> = + if takeCount < 0 then invalidArgInputMustBeNonNegative "count" takeCount + elif takeCount = 0 then empty + else + source.PushTransform { new ITransformFactory<'T,'T> with + member __.Compose outOfBand pipelineIdx next = + if takeCount = 0 then + outOfBand.StopFurtherProcessing pipelineIdx + + 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 ITransformFactory<'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 ITransformFactory<'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 ITransformFactory<'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.PushTransform { new ITransformFactory<'T,'T> with + override __.Compose _ _ next = + let mutable this = Unchecked.defaultof> + let skipper = + { new Transform<'T,'U,int>(next,(*count*)0) with + // member this.count = this.State + override this.ProcessNext (input:'T) : bool = + if this.State < index then + this.State <- this.State + 1 + false + else + TailCall.avoid (next.ProcessNext input) + + interface ISkipable with + member __.CanSkip () = + if this.State < index then + this.State <- this.State + 1 + true + else + false } + this <- skipper + upcast this } + |> tryHead + + [] + let inline tryPick f (source:ISeq<'T>) = + source.Fold (fun pipeIdx -> + { new Folder<'T, Option<'U>> (None) with + override this.ProcessNext value = + match f value with + | (Some _) as some -> + this.Result <- some + (this :> IOutOfBand).StopFurtherProcessing pipeIdx + | None -> () + Unchecked.defaultof<_> (* return value unused in Fold context *) }) + + [] + let inline tryFind f (source:ISeq<'T>) = + source.Fold (fun pipeIdx -> + { new Folder<'T, Option<'T>> (None) with + override this.ProcessNext value = + if f value then + this.Result <- Some value + (this :> IOutOfBand).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 -> + upcast { new FolderWithState<'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 :> IOutOfBand).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[]> = + if windowSize <= 0 then + invalidArgFmt "windowSize" "{0}\nwindowSize = {1}" [|SR.GetString SR.inputMustBePositive; windowSize|] + + source.PushTransform { new ITransformFactory<'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 append (source1:ISeq<'T>) (source2: ISeq<'T>) : ISeq<'T> = + match source1 with + | :? EnumerableBase<'T> as s -> s.Append source2 + | _ -> upcast (new AppendEnumerable<_>([source2; source1])) + + [] + let delay (delayed:unit->ISeq<'T>) : ISeq<'T> = + upcast (DelayedEnumerable (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 length (source:ISeq<'T>) = + match source with + | :? EnumerableBase<'T> as s -> s.Length () + | :? list<'T> as l -> l.Length + | _ -> Microsoft.FSharp.Primitives.Basics.ISeq.length source + + [] + let toArray (source:ISeq<'T>) = + 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 + ofArray array) + + [] + let sort source = + delay (fun () -> + let array = source |> toArray + Array.stableSortInPlace array + ofArray array) + + [] + let sortWith f source = + delay (fun () -> + let array = source |> toArray + Array.stableSortInPlaceWith f array + ofArray array) + + [] + let rev source = + delay (fun () -> + let array = source |> toArray + Array.Reverse array + ofArray array) + + [] + let permute f (source:ISeq<_>) = + delay (fun () -> + source + |> toArray + |> Array.permute f + |> ofArray) + + [] + let scanBack<'T,'State> f (source:ISeq<'T>) (acc:'State) : ISeq<'State> = + delay (fun () -> + let array = source |> toArray + Array.scanSubRight f array 0 (array.Length - 1) acc + |> ofArray) + + let inline foldArraySubRight f (arr: 'T[]) start fin acc = + let mutable state = acc + for i = fin downto start do + state <- f arr.[i] state + state + + [] + let inline foldBack<'T,'State> f (source: ISeq<'T>) (x:'State) = + let arr = toArray source + let len = arr.Length + foldArraySubRight f arr 0 (len - 1) x + + [] + let zip source1 source2 = + map2 (fun x y -> x,y) source1 source2 + + [] + let inline foldBack2<'T1,'T2,'State> f (source1:ISeq<'T1>) (source2:ISeq<'T2>) (x:'State) = + let zipped = zip source1 source2 + foldBack ((<||) f) zipped x + + [] + let inline reduceBack f (source:ISeq<'T>) = + let arr = toArray source + match arr.Length with + | 0 -> invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString + | len -> foldArraySubRight f arr 0 (len - 2) arr.[len - 1] + + [] + type CachedSeq<'T>(source:ISeq<'T>) = + let sync = obj () + + // Wrap a seq to ensure that it is enumerated just once and only as far as is necessary. + // + // This code is required to be thread safe. + // The necessary calls should be called at most once (include .MoveNext() = false). + // The enumerator should be disposed (and dropped) when no longer required. + //------ + // The state is (prefix,enumerator) with invariants: + // * the prefix followed by elts from the enumerator are the initial sequence. + // * the prefix contains only as many elements as the longest enumeration so far. + + let prefix = ResizeArray () + + let mutable started = false + let mutable enumeratorR = None : option> + + // function should only be called from within the lock + let oneStepTo i = + // If possible, step the enumeration to prefix length i (at most one step). + // Be speculative, since this could have already happened via another thread. + if not (i < prefix.Count) then // is a step still required? + // If not yet started, start it (create enumerator). + if not started then + started <- true + enumeratorR <- Some (source.GetEnumerator()) + + match enumeratorR with + | Some enumerator when enumerator.MoveNext() -> + prefix.Add enumerator.Current + | Some enumerator -> + enumerator.Dispose () // Move failed, dispose enumerator, + enumeratorR <- None // drop it and record finished. + | _ -> () + + let unfolding i = + // i being the next position to be returned + // A lock is needed over the reads to prefix.Count since the list may be being resized + // NOTE: we could change to a reader/writer lock here + lock sync (fun () -> + if i < prefix.Count then + Some (prefix.[i], i+1) + else + oneStepTo i + if i < prefix.Count then + Some (prefix.[i], i+1) + else + None) + + let cached : ISeq<'T> = upcast (new UnfoldEnumerable<'T,'T,int>(unfolding, 0, IdentityFactory.Instance, 1)) + + interface System.IDisposable with + member __.Dispose() = + lock sync (fun () -> + prefix.Clear() + + enumeratorR + |> Option.iter IEnumerator.dispose + + started <- false + enumeratorR <- None) + + interface System.Collections.Generic.IEnumerable<'T> with + member __.GetEnumerator() = cached.GetEnumerator() + + interface System.Collections.IEnumerable with + member __.GetEnumerator() = (cached:>IEnumerable).GetEnumerator() + + interface ISeq<'T> with + member __.PushTransform next = cached.PushTransform next + member __.Fold f = cached.Fold f + + member this.Clear() = (this :> IDisposable).Dispose () + + [] + let cache (source:ISeq<'T>) : ISeq<'T> = + upcast (new CachedSeq<_> (source)) + + [] + let collect f sources = map f sources |> concat + + [] + let allPairs (source1:ISeq<'T1>) (source2:ISeq<'T2>) : ISeq<'T1 * 'T2> = + checkNonNull "source1" source1 + checkNonNull "source2" source2 + let cached = cache source2 + source1 |> collect (fun x -> cached |> map (fun y -> x,y)) + + [] + let toList (source : ISeq<'T>) = + match source with + | :? list<'T> as lst -> lst + | _ -> Microsoft.FSharp.Primitives.Basics.List.ofISeq source + + [] + let replicate<'T> count (x:'T) : ISeq<'T> = + if count < 0 then raise (ArgumentOutOfRangeException "count") + upcast (new InitEnumerable<'T,'T>(Nullable count, (fun _ -> x), IdentityFactory.Instance, 1)) + + [] + let isEmpty (source : ISeq<'T>) = + match source with + | :? list<'T> as lst -> lst.IsEmpty + | _ -> + use ie = source.GetEnumerator() + not (ie.MoveNext()) + + [] + let cast (source: IEnumerable) : ISeq<'T> = + match source with + | :? ISeq<'T> as s -> s + | :? ISeq as s -> s |> map unbox // covariant on ref types + | _ -> + mkSeq (fun () -> IEnumerator.cast (source.GetEnumerator())) |> ofSeq + + [] + let chunkBySize chunkSize (source : ISeq<'T>) : ISeq<'T[]> = + if chunkSize <= 0 then invalidArgFmt "chunkSize" "{0}\nchunkSize = {1}" + [|SR.GetString SR.inputMustBePositive; chunkSize|] + + source.PushTransform { new ITransformFactory<'T,'T[]> with + member __.Compose outOfBand pipeIdx next = + upcast { + new TransformWithPostProcessing<'T,'U,Values<'T[],int>>(next,Values<'T[],int>(Array.zeroCreateUnchecked chunkSize, 0)) with + override this.ProcessNext (input:'T) : bool = + this.State._1.[this.State._2] <- input + this.State._2 <- this.State._2 + 1 + if this.State._2 <> chunkSize then false + else + this.State._2 <- 0 + let tmp = this.State._1 + this.State._1 <- Array.zeroCreateUnchecked chunkSize + TailCall.avoid (next.ProcessNext tmp) + override this.OnComplete _ = + if this.State._2 > 0 then + System.Array.Resize (&this.State._1, this.State._2) + next.ProcessNext this.State._1 |> ignore + override this.OnDispose () = () }} + + let mkDelayedSeq (f: unit -> IEnumerable<'T>) = mkSeq (fun () -> f().GetEnumerator()) |> ofSeq + + [] + let splitInto count (source:ISeq<'T>) : ISeq<'T[]> = + if count <= 0 then invalidArgFmt "count" "{0}\ncount = {1}" + [|SR.GetString SR.inputMustBePositive; count|] + mkDelayedSeq (fun () -> + source |> toArray |> Array.splitInto count :> seq<_>) + + let inline indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException(SR.GetString(SR.keyNotFoundAlt))) + + [] + let find f source = + match tryFind f source with + | None -> indexNotFound() + | Some x -> x + + [] + let findIndex p (source:ISeq<_>) = + 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 findBack f source = + source |> toArray |> Array.findBack f + + [] + let findIndexBack f source = + source |> toArray |> Array.findIndexBack f + + [] + let pick f source = + match tryPick f source with + | None -> indexNotFound() + | Some x -> x + + [] + let mapFold<'T,'State,'Result> (f: 'State -> 'T -> 'Result * 'State) acc source = + let arr,state = source |> toArray |> Array.mapFold f acc + ofArray arr, state + + [] + let mapFoldBack<'T,'State,'Result> (f: 'T -> 'State -> 'Result * 'State) source acc = + let array = source |> toArray + let arr,state = Array.mapFoldBack f array acc + ofArray arr, state + + 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 + + [] + let item i (source : ISeq<'T>) = + if i < 0 then invalidArgInputMustBeNonNegative "index" i + use e = source.GetEnumerator() + nth i e + + [] + let inline sortDescending source = + let inline compareDescending a b = compare b a + sortWith compareDescending source + + [] + let inline sortByDescending keyf source = + let inline compareDescending a b = compare (keyf b) (keyf a) + sortWith compareDescending source + + [] + let tryFindBack f (source : ISeq<'T>) = + source |> toArray |> Array.tryFindBack f + + [] + let tryFindIndexBack f (source : ISeq<'T>) = + source |> toArray |> Array.tryFindIndexBack f + + [] + let zip3 source1 source2 source3 = + map2 (fun x (y,z) -> x,y,z) source1 (zip source2 source3) diff --git a/src/fsharp/FSharp.Core/iseq.fsi b/src/fsharp/FSharp.Core/iseq.fsi new file mode 100644 index 00000000000..0c78d1e567e --- /dev/null +++ b/src/fsharp/FSharp.Core/iseq.fsi @@ -0,0 +1,406 @@ +// 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 + open Microsoft.FSharp.Collections.SeqComposition + + [] + module ISeq = + module Core = + /// 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 + + + /// An activity that transforms the input from 'T to 'U, using 'State. It's intended usage + /// is as a base class for an object expression that will be created + /// in the ITransformFactory's Compose function. + [] + 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 + + /// An activity that transforms the input from 'T to 'U, using 'State + /// and performs some post processing on the pipeline, either in the case of the stream + /// ending sucessfully or when disposed. It's intended usage + /// is as a base class for an object expression that will be created + /// in the ITransformFactory's Compose function. + [] + 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 FolderWithState<'T,'Result,'State> = + inherit Folder<'T,'Result> + new : 'Result*'State -> FolderWithState<'T,'Result,'State> + val mutable State : 'State + + /// Folder is a base class to assist with fold-like operations + /// and performs some post processing on the pipeline, either in the case of the stream + /// ending sucessfully or when disposed. It's intended usage + /// is as a base class for an object expression that will be used from within + /// the Fold function. + [] + type FolderWithPostProcessing<'T,'Result,'State> = + inherit FolderWithState<'T,'Result,'State> + new : 'Result*'State -> FolderWithPostProcessing<'T,'Result,'State> + abstract OnDispose : unit -> unit + abstract OnComplete : PipeIdx -> unit + + open Core + + /// ofResizeArrayUnchecked creates an ISeq over a ResizeArray that accesses the underlying + /// structure via Index rather than via the GetEnumerator function. This provides faster access + /// but doesn't check the version of the underlying object which means care has to be taken + /// to ensure that it is not modified which the result ISeq exists. + [] + 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 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 length: source:ISeq<'T> -> int + + [] + 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> + + [] + val scanBack<'T,'State> : folder:('T->'State->'State) -> source:ISeq<'T> -> state:'State -> ISeq<'State> + + [] + val zip: source1:ISeq<'T1> -> source2:ISeq<'T2> -> ISeq<'T1 * 'T2> + + [] + val inline reduceBack: reduction:('T->'T->'T) -> source:ISeq<'T> -> 'T + + [] + val inline foldBack<'T,'State> : folder:('T->'State->'State) -> source:ISeq<'T> -> state:'State -> 'State + + [] + val inline foldBack2<'T1,'T2,'State> : folder:('T1->'T2->'State->'State) -> source1:ISeq<'T1> -> source2:ISeq<'T2> -> state:'State -> 'State + + 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 + + [] + val cache: source:ISeq<'T> -> ISeq<'T> + + [] + val collect: mapping:('T -> 'Collection) -> source:ISeq<'T> -> ISeq<'U> when 'Collection :> ISeq<'U> + + [] + val allPairs: source1:ISeq<'T1> -> source2:ISeq<'T2> -> ISeq<'T1 * 'T2> + + [] + val toList: source:ISeq<'T> -> 'T list + + [] + val replicate: count:int -> initial:'T -> ISeq<'T> + + [] + val isEmpty: source:ISeq<'T> -> bool + + [] + val cast: source:IEnumerable -> ISeq<'T> + + [] + val chunkBySize: chunkSize:int -> source:ISeq<'T> -> ISeq<'T[]> + + [] + val splitInto: count:int -> source:ISeq<'T> -> ISeq<'T[]> + + [] + val find: predicate:('T -> bool) -> source:ISeq<'T> -> 'T + + [] + val findBack: predicate:('T -> bool) -> source:ISeq<'T> -> 'T + + [] + val findIndex: predicate:('T -> bool) -> source:ISeq<'T> -> int + + [] + val findIndexBack: predicate:('T -> bool) -> source:ISeq<'T> -> int + + [] + val pick: chooser:('T -> 'U option) -> source:ISeq<'T> -> 'U + + [] + val mapFold<'T,'State,'Result> : mapping:('State -> 'T -> 'Result * 'State) -> state:'State -> source:ISeq<'T> -> ISeq<'Result> * 'State + + [] + val mapFoldBack<'T,'State,'Result> : mapping:('T -> 'State -> 'Result * 'State) -> source:ISeq<'T> -> state:'State -> ISeq<'Result> * 'State + + [] + val item: index:int -> source:ISeq<'T> -> 'T + + [] + val singleton: value:'T -> ISeq<'T> + + [] + val inline sortDescending : source:ISeq<'T> -> ISeq<'T> when 'T : comparison + + [] + val inline sortByDescending : projection:('T -> 'Key) -> source:ISeq<'T> -> ISeq<'T> when 'Key : comparison + + [] + val tryFindBack: predicate:('T -> bool) -> source:ISeq<'T> -> 'T option + + [] + val tryFindIndexBack : predicate:('T -> bool) -> source:ISeq<'T> -> int option + + [] + val zip3: source1:ISeq<'T1> -> source2:ISeq<'T2> -> source3:ISeq<'T3> -> ISeq<'T1 * 'T2 * 'T3> diff --git a/src/fsharp/FSharp.Core/list.fs b/src/fsharp/FSharp.Core/list.fs index 66cc2139887..f41dbe92459 100644 --- a/src/fsharp/FSharp.Core/list.fs +++ b/src/fsharp/FSharp.Core/list.fs @@ -7,7 +7,6 @@ namespace Microsoft.FSharp.Collections open Microsoft.FSharp.Core.LanguagePrimitives open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators open Microsoft.FSharp.Collections - open Microsoft.FSharp.Core.CompilerServices open System.Collections.Generic #if FX_RESHAPED_REFLECTION open System.Reflection @@ -59,7 +58,7 @@ namespace Microsoft.FSharp.Collections let countByValueType (projection:'T->'Key) (list:'T list) = countByImpl HashIdentity.Structural<'Key> projection id list // Wrap a StructBox around all keys in case the key type is itself a type using null as a representation - let countByRefType (projection:'T->'Key) (list:'T list) = countByImpl RuntimeHelpers.StructBox<'Key>.Comparer (fun t -> RuntimeHelpers.StructBox (projection t)) (fun sb -> sb.Value) list + let countByRefType (projection:'T->'Key) (list:'T list) = countByImpl StructBox<'Key>.Comparer (fun t -> StructBox (projection t)) (fun sb -> sb.Value) list [] let countBy (projection:'T->'Key) (list:'T list) = @@ -432,7 +431,7 @@ namespace Microsoft.FSharp.Collections let groupByValueType (keyf:'T->'Key) (list:'T list) = groupByImpl HashIdentity.Structural<'Key> keyf id list // 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) (list:'T list) = groupByImpl RuntimeHelpers.StructBox<'Key>.Comparer (fun t -> RuntimeHelpers.StructBox (keyf t)) (fun sb -> sb.Value) list + let groupByRefType (keyf:'T->'Key) (list:'T list) = groupByImpl StructBox<'Key>.Comparer (fun t -> StructBox (keyf t)) (fun sb -> sb.Value) list [] let groupBy (keyf:'T->'Key) (list:'T list) = @@ -522,10 +521,10 @@ namespace Microsoft.FSharp.Collections sortWith compareDescending xs [] - let ofSeq source = Seq.toList source + let ofSeq<'T> (source:seq<'T>) : list<'T> = Microsoft.FSharp.Primitives.Basics.List.ofSeq source [] - let toSeq list = Seq.ofList list + let toSeq<'T> (list:list<'T>) : seq<'T> = (list :> seq<'T>) [] let findIndex f list = diff --git a/src/fsharp/FSharp.Core/local.fs b/src/fsharp/FSharp.Core/local.fs index d632dd29df8..b05c7ece85d 100644 --- a/src/fsharp/FSharp.Core/local.fs +++ b/src/fsharp/FSharp.Core/local.fs @@ -86,6 +86,7 @@ open Microsoft.FSharp.Core.ICloneableExtensions module internal List = + open Microsoft.FSharp.Collections.SeqComposition let arrayZeroCreate (n:int) = (# "newarr !0" type ('T) n : 'T array #) @@ -544,10 +545,35 @@ module internal List = res <- arr.[i] :: res res + type FoldToList<'T> () = + inherit Folder<'T, list<'T>>([]) + + let mutable first = true + let mutable cons = Unchecked.defaultof<_> + + override this.ProcessNext input = + if first then + first <- false + this.Result <- freshConsNoTail input + cons <- this.Result + else + let cons2 = freshConsNoTail input + setFreshConsTail cons cons2 + cons <- cons2 + true (* result unused in fold *) + + override this.ChainComplete _ = + if not first then + setFreshConsTail cons [] + + let ofISeq (s : ISeq<'T>) = + s.Fold (fun _ -> upcast FoldToList()) + let inline ofSeq (e : IEnumerable<'T>) = match e with | :? list<'T> as l -> l | :? ('T[]) as arr -> ofArray arr + | :? ISeq<'T> as s -> ofISeq s | _ -> use ie = e.GetEnumerator() if not (ie.MoveNext()) then [] @@ -923,6 +949,75 @@ module internal List = module internal Array = open System + open System.Collections.Generic + open Microsoft.FSharp.Collections.SeqComposition + +#if FX_NO_ARRAY_KEY_SORT + // Mimic behavior of BCL QSort routine, used under the hood by various array sorting APIs + let qsort<'Key,'Value>(keys : 'Key[], values : 'Value[], start : int, last : int, comparer : IComparer<'Key>) = + let valuesExist = + match values with + | null -> false + | _ -> true + + let swap (p1, p2) = + let tk = keys.[p1] + keys.[p1] <- keys.[p2] + keys.[p2] <- tk + if valuesExist then + let tv = values.[p1] + values.[p1] <- values.[p2] + values.[p2] <- tv + + let partition (left, right, pivot) = + let value = keys.[pivot] + swap (pivot, right) + let mutable store = left + + for i in left..(right - 1) do + if comparer.Compare(keys.[i],value) < 0 then + swap(i, store) + store <- store + 1 + + swap (store, right) + store + + let rec qs (left, right) = + if left < right then + let pivot = left + (right-left)/2 + let newpivot = partition(left,right,pivot) + qs(left,newpivot - 1) + qs(newpivot+1,right) + + qs(start, last) + + type System.Array with + static member Sort<'Key,'Value>(keys : 'Key[], values : 'Value[], comparer : IComparer<'Key>) = + let valuesExist = + match values with + | null -> false + | _ -> true + match keys,values with + | null,_ -> raise (ArgumentNullException()) + | _,_ when valuesExist && (keys.Length <> values.Length) -> raise (ArgumentException()) + | _,_ -> qsort(keys, values, 0, keys.Length-1, comparer) + + static member Sort<'Key,'Value when 'Key : comparison>(keys : 'Key[], values : 'Value[]) = + let valuesExist = + match values with + | null -> false + | _ -> true + match keys,values with + | null,_ -> raise (ArgumentNullException()) + | _,_ when valuesExist && (keys.Length <> values.Length) -> raise (ArgumentException()) + | _,_ -> qsort(keys,values,0,keys.Length-1,LanguagePrimitives.FastGenericComparer<'Key>) + + static member Sort<'Key,'Value>(keys : 'Key[], values : 'Value[], start : int, length : int, comparer : IComparer<'Key>) = + match keys with + | null -> raise (ArgumentNullException()) + | _ -> qsort(keys,values,start,start+length-1,comparer) +#else +#endif let inline fastComparerForArraySort<'t when 't : comparison> () = LanguagePrimitives.FastGenericComparerCanBeNull<'t> @@ -1119,3 +1214,59 @@ module internal Array = res.[i] <- subUnchecked !startIndex minChunkSize array startIndex := !startIndex + minChunkSize res + + type FoldToArray<'T> () = + inherit Folder<'T, array<'T>>(Unchecked.defaultof<_>) + + let mutable tmp = ResizeArray () + + override this.ProcessNext input = + tmp.Add input + true (* result unused in fold *) + + override this.ChainComplete _ = + this.Result <- tmp.ToArray () + + let ofISeq (s : ISeq<'T>) = + s.Fold (fun _ -> upcast FoldToArray()) + + let ofSeq (source : seq<'T>) = + 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 = zeroCreateUnchecked res.Count + res.CopyTo(arr, 0) + arr + | :? ISeq<'T> as s -> ofISeq s +#if !FSCORE_PORTABLE_OLD + | :? IReadOnlyCollection<'T> as col -> + let res = zeroCreateUnchecked col.Count : 'T[] + let mutable idx = 0 + for x in source do + res.[idx] <- x + idx <- idx + 1 + res +#endif + | _ -> + let res = ResizeArray source + res.ToArray() + + let toSeq (source : array<'T>) : seq<'T> = + { new IEnumerable<'T> with + member this.GetEnumerator(): Collections.IEnumerator = + (source:>System.Collections.IEnumerable).GetEnumerator () + member this.GetEnumerator(): IEnumerator<'T> = + (source:>IEnumerable<'T>).GetEnumerator () } + +module internal ISeq = + open Microsoft.FSharp.Collections.SeqComposition + + let length (source:ISeq<_>) = + source.Fold (fun _ -> + { new Folder<'T,int>(0) with + override this.ProcessNext v = + this.Result <- this.Result + 1 + Unchecked.defaultof<_> (* return value unused in Fold context *) }) diff --git a/src/fsharp/FSharp.Core/local.fsi b/src/fsharp/FSharp.Core/local.fsi index dcf8f2a6e15..4df794ac9e6 100644 --- a/src/fsharp/FSharp.Core/local.fsi +++ b/src/fsharp/FSharp.Core/local.fsi @@ -22,6 +22,7 @@ namespace Microsoft.FSharp.Primitives.Basics open Microsoft.FSharp.Core open Microsoft.FSharp.Collections +open Microsoft.FSharp.Collections.SeqComposition module internal List = val allPairs : 'T1 list -> 'T2 list -> ('T1 * 'T2) list @@ -61,6 +62,7 @@ module internal List = val take : int -> 'T list -> 'T list val takeWhile : ('T -> bool) -> 'T list -> 'T list val toArray : 'T list -> 'T[] + val ofISeq : ISeq<'T> -> 'T List val inline ofSeq : seq<'T> -> 'T List val splitAt : int -> 'T list -> ('T list * 'T list) val truncate : int -> 'T list -> 'T list @@ -68,35 +70,24 @@ module internal List = module internal Array = // The input parameter should be checked by callers if necessary val inline zeroCreateUnchecked : int -> 'T[] - val inline init : int -> (int -> 'T) -> 'T[] - val splitInto : int -> 'T[] -> 'T[][] - val findBack: predicate:('T -> bool) -> array:'T[] -> 'T - val tryFindBack: predicate:('T -> bool) -> array:'T[] -> 'T option - val findIndexBack: predicate:('T -> bool) -> array:'T[] -> int - val tryFindIndexBack: predicate:('T -> bool) -> array:'T[] -> int option - val mapFold : ('State -> 'T -> 'U * 'State) -> 'State -> 'T[] -> 'U[] * 'State - val mapFoldBack : ('T -> 'State -> 'U * 'State) -> 'T[] -> 'State -> 'U[] * 'State - val permute : indexMap:(int -> int) -> 'T[] -> 'T[] - val scanSubRight: f:('T -> 'State -> 'State) -> array:'T[] -> start:int -> fin:int -> initState:'State -> 'State[] - val inline subUnchecked : int -> int -> 'T[] -> 'T[] - val unstableSortInPlaceBy: projection:('T -> 'Key) -> array:'T[] -> unit when 'Key : comparison - val unstableSortInPlace: array:'T[] -> unit when 'T : comparison - val stableSortInPlaceBy: projection:('T -> 'Key) -> array:'T[] -> unit when 'Key : comparison - val stableSortInPlaceWith: comparer:('T -> 'T -> int) -> array:'T[] -> unit - val stableSortInPlace: array:'T[] -> unit when 'T : comparison + val ofSeq : seq<'T> -> array<'T> + val toSeq : array<'T> -> seq<'T> + +module internal ISeq = + val length : ISeq<'T> -> int \ No newline at end of file diff --git a/src/fsharp/FSharp.Core/map.fs b/src/fsharp/FSharp.Core/map.fs index f58abfcda7a..0fe3ac0357c 100644 --- a/src/fsharp/FSharp.Core/map.fs +++ b/src/fsharp/FSharp.Core/map.fs @@ -332,12 +332,6 @@ namespace Microsoft.FSharp.Collections let toArray m = m |> toList |> Array.ofList let ofList comparer l = List.fold (fun acc (k,v) -> add comparer k v acc) empty l - let rec mkFromEnumerator comparer acc (e : IEnumerator<_>) = - if e.MoveNext() then - let (x,y) = e.Current - mkFromEnumerator comparer (add comparer x y acc) e - else acc - let ofArray comparer (arr : array<_>) = let mutable res = empty for (x,y) in arr do @@ -348,10 +342,7 @@ namespace Microsoft.FSharp.Collections match c with | :? array<'Key * 'T> as xs -> ofArray comparer xs | :? list<'Key * 'T> as xs -> ofList comparer xs - | _ -> - use ie = c.GetEnumerator() - mkFromEnumerator comparer empty ie - + | _ -> Seq.fold (fun acc (k,v) -> add comparer k v acc) empty c let copyToArray s (arr: _[]) i = let j = ref i diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 5927be7f511..ebb9250266f 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -3468,6 +3468,68 @@ namespace Microsoft.FSharp.Core //============================================================================ //============================================================================ +namespace Microsoft.FSharp.Collections.SeqComposition + open System + open System.Collections + open System.Collections.Generic + open Microsoft.FSharp.Core + open BasicInlinedOperations + open LanguagePrimitives.IntrinsicOperators + + type PipeIdx = int + + type IOutOfBand = + abstract StopFurtherProcessing : PipeIdx -> unit + abstract ListenForStopFurtherProcessing : Action -> unit + + [] + type Activity() = + abstract ChainComplete : PipeIdx -> unit + abstract ChainDispose : unit -> unit + + [] + type Activity<'T> () = + inherit Activity() + abstract ProcessNext : input:'T -> bool + + [] + type Activity<'T,'U> () = + inherit Activity<'T>() + + [] + type Folder<'T,'Result>(initalResult:'Result) = + inherit Activity<'T,'T>() + + let mutable listeners = BasicInlinedOperations.unsafeDefault> + let mutable result = initalResult + let mutable haltedIdx = 0 + + member __.Result with get () = result and set value = result <- value + member __.HaltedIdx with get () = haltedIdx + + interface IOutOfBand with + member this.StopFurtherProcessing pipeIdx = + let currentIdx = haltedIdx + haltedIdx <- pipeIdx + if currentIdx = 0 && haltedIdx <> 0 then + match listeners with + | null -> () + | a -> a.Invoke pipeIdx + + member this.ListenForStopFurtherProcessing action = + listeners <- Delegate.Combine (listeners, action) :?> Action + + override this.ChainComplete _ = () + override this.ChainDispose () = () + + type ITransformFactory<'T,'U> = + abstract Compose<'V> : IOutOfBand -> PipeIdx -> Activity<'U,'V> -> Activity<'T,'V> + + type ISeq<'T> = + inherit IEnumerable<'T> + abstract member PushTransform<'U> : ITransformFactory<'T,'U> -> ISeq<'U> + abstract member Fold<'Result> : f:(PipeIdx->Folder<'T,'Result>) -> 'Result + namespace Microsoft.FSharp.Collections //------------------------------------------------------------------------- @@ -3481,6 +3543,7 @@ namespace Microsoft.FSharp.Collections open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions open Microsoft.FSharp.Core.BasicInlinedOperations + open Microsoft.FSharp.Collections.SeqComposition [] #if !FX_NO_DEBUG_PROXIES @@ -3495,6 +3558,7 @@ namespace Microsoft.FSharp.Collections type List<'T> = | ([]) : 'T list | (::) : Head: 'T * Tail: 'T list -> 'T list + interface Microsoft.FSharp.Collections.SeqComposition.ISeq<'T> interface System.Collections.Generic.IEnumerable<'T> interface System.Collections.IEnumerable @@ -3545,6 +3609,7 @@ namespace Microsoft.FSharp.Collections let notStarted() = raise (new System.InvalidOperationException(SR.GetString(SR.enumerationNotStarted))) let alreadyFinished() = raise (new System.InvalidOperationException(SR.GetString(SR.enumerationAlreadyFinished))) let outOfRange() = raise (System.IndexOutOfRangeException(SR.GetString(SR.indexOutOfBounds))) + let noReset() = raise (new System.NotSupportedException(SR.GetString(SR.resetNotSupported))) let nonempty x = match x with [] -> false | _ -> true // optimized mutation-based implementation. This code is only valid in fslib, where mutation of private @@ -3640,6 +3705,92 @@ namespace Microsoft.FSharp.Collections | [] -> outOfRange() loop n l + module ListSeqImplementation = + type ComposedFactory<'T,'U,'V> private (first:ITransformFactory<'T,'U>, second:ITransformFactory<'U,'V>) = + interface ITransformFactory<'T,'V> with + member 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:ITransformFactory<'T,'U>) (second:ITransformFactory<'U,'V>) : ITransformFactory<'T,'V> = + upcast ComposedFactory(first, second) + + type Result<'T>() = + inherit Folder<'T,'T>(unsafeDefault<'T>) + + member val SeqState = 1(*NotStarted*) with get, set + + override this.ProcessNext (input:'T) : bool = + this.Result <- input + true + + type ListEnumerator<'T,'U>(alist:list<'T>, activity:Activity<'T,'U>, result:Result<'U>) = + 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 <- 2(*Finished*) + activity.ChainComplete result.HaltedIdx + false + + interface System.IDisposable with + member __.Dispose () : unit = + activity.ChainDispose () + + interface System.Collections.IEnumerator with + member this.Current : obj = box (this :> IEnumerator<'U>).Current + member __.MoveNext () = + result.SeqState <- 0(*InProcess*) + moveNext list + + member __.Reset () : unit = PrivateListHelpers.noReset () + + interface IEnumerator<'U> with + member __.Current = + if result.SeqState = 0(*InProcess*) then result.Result + elif result.SeqState = 1(*NotStarted*) then PrivateListHelpers.notStarted() + else PrivateListHelpers.alreadyFinished() + + type ListEnumerable<'T,'U>(alist:list<'T>, transformFactory:ITransformFactory<'T,'U>, pipeIdx:PipeIdx) = + interface System.Collections.IEnumerable with + member this.GetEnumerator () : System.Collections.IEnumerator = + upcast (this :> IEnumerable<'U>).GetEnumerator () + + interface System.Collections.Generic.IEnumerable<'U> with + member this.GetEnumerator () : System.Collections.Generic.IEnumerator<'U> = + let result = Result<'U> () + let activity = transformFactory.Compose (result :> IOutOfBand) pipeIdx result + upcast (new ListEnumerator<'T,'U>(alist, activity, result)) + + interface ISeq<'U> with + member __.PushTransform (next:ITransformFactory<'U,'V>) : ISeq<'V> = + upcast (new ListEnumerable<'T,'V>(alist, ComposedFactory.Combine transformFactory next, pipeIdx+1)) + + member this.Fold<'Result> (createFolder:PipeIdx->Folder<'U,'Result>) = + let result = createFolder (pipeIdx+1) + let consumer = transformFactory.Compose (result :> IOutOfBand) pipeIdx result + try + let mutable lst = alist + while + ( match lst with + | hd :: tl when result.HaltedIdx = 0 -> + ignore (consumer.ProcessNext hd) + lst <- tl + true + | _ -> false + ) do () + + consumer.ChainComplete result.HaltedIdx + finally + consumer.ChainDispose () + result.Result + type List<'T> with #if !FX_NO_DEBUG_DISPLAYS [] @@ -3688,6 +3839,28 @@ namespace Microsoft.FSharp.Collections if i > j then [] else PrivateListHelpers.sliceTake (j-i) (PrivateListHelpers.sliceSkip i l) + interface ISeq<'T> with + member this.PushTransform<'U> (next:ITransformFactory<'T,'U>) = + upcast (new ListSeqImplementation.ListEnumerable<'T,'U>(this, next, 1)) + + member this.Fold<'Result> (createFolder:PipeIdx->Folder<'T,'Result>) = + let result = createFolder 1 + try + let mutable lst = this + while + ( match lst with + | hd :: tl when result.HaltedIdx = 0 -> + ignore (result.ProcessNext hd) + lst <- tl + true + | _ -> false + ) do () + + result.ChainComplete result.HaltedIdx + finally + result.ChainDispose () + result.Result + interface IEnumerable<'T> with member l.GetEnumerator() = PrivateListHelpers.mkListEnumerator l @@ -3701,12 +3874,11 @@ namespace Microsoft.FSharp.Collections type seq<'T> = IEnumerable<'T> - + //------------------------------------------------------------------------- // Operators //------------------------------------------------------------------------- - namespace Microsoft.FSharp.Core open System @@ -3719,13 +3891,11 @@ namespace Microsoft.FSharp.Core open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions open Microsoft.FSharp.Core.BasicInlinedOperations open Microsoft.FSharp.Collections - - + open Microsoft.FSharp.Collections.SeqComposition [] module Operators = - #if MULTI_DIMENSIONAL_EXTENSION_PROPERTIES type ``[,]``<'T> with [] @@ -5122,6 +5292,99 @@ namespace Microsoft.FSharp.Core | Running = 1 | Finished = 2 + type ComposedFactory<'T,'U,'V> private (first:ITransformFactory<'T,'U>, second:ITransformFactory<'U,'V>) = + interface ITransformFactory<'T,'V> with + member 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:ITransformFactory<'T,'U>) (second:ITransformFactory<'U,'V>) : ITransformFactory<'T,'V> = + upcast ComposedFactory(first, second) + + type IdentityFactory<'T> private () = + static let singleton : ITransformFactory<'T,'T> = upcast (IdentityFactory<'T>()) + static member Instance = singleton + interface ITransformFactory<'T,'T> with + member __.Compose<'V> (_outOfBand:IOutOfBand) (_pipeIdx:PipeIdx) (next:Activity<'T,'V>) : Activity<'T,'V> = next + + type SetResultToInput<'T>() = + inherit Folder<'T,'T>(Unchecked.defaultof<'T>) + override this.ProcessNext (input:'T) : bool = + this.Result <- input + true + + type SeqSourceEnumerator<'T,'U>(source:IEnumerator<'T>, activity:Activity<'T,'U>, folder:SetResultToInput<'U>) = + let mutable state = Mode.NotStarted + + let rec moveNext () = + if (folder.HaltedIdx = 0) && source.MoveNext () then + if activity.ProcessNext source.Current then + true + else + moveNext () + else + state <- Mode.Finished + activity.ChainComplete folder.HaltedIdx + false + + interface IEnumerator with + member this.Current : obj = box (this :> IEnumerator<'U>).Current + member __.Reset () : unit = source.Reset () + member __.MoveNext () = + state <- Mode.Running + moveNext () + + interface IEnumerator<'U> with + member __.Current = + if state = Mode.Running then folder.Result + else + match state with + | Mode.NotStarted -> notStarted() + | Mode.Finished -> alreadyFinished() + | _ -> failwith "library implementation error: all states should have been handled" + + interface IDisposable with + member __.Dispose () = + try + source.Dispose () + finally + activity.ChainDispose () + + type ISeqSource<'T> = + abstract member GetEnumerator : unit -> IEnumerator<'T> + abstract member Fold<'Result,'U> : f:(PipeIdx->Folder<'U,'Result>) -> ITransformFactory<'T,'U> -> PipeIdx -> 'Result + + type SeqSourceEnumerable<'T,'U>(source:ISeqSource<'T>, current:ITransformFactory<'T,'U>, pipeIdx:PipeIdx) = + interface IEnumerable<'U> with + member __.GetEnumerator () = + let folder = SetResultToInput<'U>() + upcast (new SeqSourceEnumerator<'T,'U>(source.GetEnumerator (), current.Compose (folder :> IOutOfBand) pipeIdx folder, folder)) + + interface IEnumerable with + member __.GetEnumerator () = + let folder = SetResultToInput<'U>() + upcast (new SeqSourceEnumerator<'T,'U>(source.GetEnumerator (), current.Compose (folder :> IOutOfBand) pipeIdx folder, folder)) + + interface ISeq<'U> with + member __.PushTransform (next:ITransformFactory<'U,'V>) : ISeq<'V> = + upcast (new SeqSourceEnumerable<'T,'V>(source, ComposedFactory.Combine current next, pipeIdx+1)) + + member this.Fold<'Result> (f:PipeIdx->Folder<'U,'Result>) = + source.Fold f current pipeIdx + + type SeqSourceEnumerableThin<'U>(source:ISeqSource<'U>) = + interface IEnumerable<'U> with + member __.GetEnumerator () = source.GetEnumerator () + + interface IEnumerable with + member __.GetEnumerator () = upcast (source.GetEnumerator ()) + + interface ISeq<'U> with + member __.PushTransform (next:ITransformFactory<'U,'V>) : ISeq<'V> = + upcast (new SeqSourceEnumerable<'U,'V>(source, next, 1)) + + member this.Fold<'Result> (f:PipeIdx->Folder<'U,'Result>) = + source.Fold f IdentityFactory.Instance 1 + [] type BaseRangeEnumerator<'T>() = // Generate enumerator from mutable state "z". @@ -5333,11 +5596,23 @@ namespace Microsoft.FSharp.Core false else false } - { new IEnumerable<'T> with + let source = { new ISeqSource<'T> with member __.GetEnumerator () = singleStepRangeEnumerator () - - interface IEnumerable with - member __.GetEnumerator () = (singleStepRangeEnumerator ()) :> IEnumerator } + member __.Fold<'Result,'Output> (createFolder:PipeIdx->Folder<'Output,'Result>) (transformFactory:ITransformFactory<'T,'Output>) pipeIdx : 'Result = + let result = createFolder (pipeIdx+1) + let consumer = transformFactory.Compose (result :> IOutOfBand) pipeIdx result + try + let mutable i : 'T = n + while result.HaltedIdx = 0 && i <= m do + consumer.ProcessNext i |> ignore + i <- i + LanguagePrimitives.GenericOne + + consumer.ChainComplete result.HaltedIdx + result.Result + finally + consumer.ChainDispose () } + + upcast (SeqSourceEnumerableThin<'T> source) // For RangeStepGeneric, zero and add are functions representing the static resolution of GenericZero and (+) // for the particular static type. diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi index 18501806161..ecc2442a778 100644 --- a/src/fsharp/FSharp.Core/prim-types.fsi +++ b/src/fsharp/FSharp.Core/prim-types.fsi @@ -1776,6 +1776,76 @@ namespace Microsoft.FSharp.Core /// Represents an Error or a Failure. The code failed with a value of 'TError representing what went wrong. | Error of ErrorValue:'TError +namespace Microsoft.FSharp.Collections.SeqComposition + open System + open System.Collections + open System.Collections.Generic + open Microsoft.FSharp.Core + + /// PipeIdx denotes the index of the element within the pipeline. 0 denotes the + /// source of the chain. + type PipeIdx = int + + /// Used within the pipline to provide out of band communications + type IOutOfBand = + /// Stop the processing of any further items down the pipeline + abstract StopFurtherProcessing : PipeIdx -> unit + /// Add a Action delegate that gets notified if StopFurtherProcessing is called + abstract ListenForStopFurtherProcessing : Action -> 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 : PipeIdx -> unit + /// OnDispose is used to cleanup the stream. It is always called at the last operation + /// after the enumeration has completed. + abstract ChainDispose : unit -> unit + + /// Activity is the base class of all elements within the pipeline + [] + type Activity<'T> = + inherit Activity + new : unit -> Activity<'T> + abstract member ProcessNext : input:'T -> bool + + /// Activity is the base class of all elements within the pipeline, carrying result type + [] + type Activity<'T,'U> = + inherit Activity<'T> + new : unit -> Activity<'T,'U> + + /// 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> = + inherit Activity<'T,'T> + new : 'Result -> Folder<'T,'Result> + interface IOutOfBand + member Result : 'Result with get, set + member HaltedIdx : PipeIdx with get + override ChainComplete : PipeIdx -> unit + override ChainDispose : unit -> unit + + /// ITransformFactory provides composition of Activities. Its intended to have a specialization + /// for each type of ISeq Activity. ISeq's PushTransform method is used to build a stack + /// of Actvities that will be composed. + type ITransformFactory<'T,'U> = + abstract member Compose : IOutOfBand -> PipeIdx -> Activity<'U,'V> -> Activity<'T,'V> + + /// ISeq<'T> is an extension to seq<'T> that provides the avilty to compose Activities + /// as well as Fold the current Activity pipeline. + type ISeq<'T> = + inherit System.Collections.Generic.IEnumerable<'T> + abstract member PushTransform : ITransformFactory<'T,'U> -> ISeq<'U> + abstract member Fold<'Result> : f:(PipeIdx->Folder<'T,'Result>) -> 'Result + namespace Microsoft.FSharp.Collections open System @@ -1826,6 +1896,7 @@ namespace Microsoft.FSharp.Collections /// The list with head appended to the front of tail. static member Cons : head:'T * tail:'T list -> 'T list + interface Microsoft.FSharp.Collections.SeqComposition.ISeq<'T> interface System.Collections.Generic.IEnumerable<'T> interface System.Collections.IEnumerable @@ -1846,8 +1917,6 @@ namespace Microsoft.FSharp.Collections /// An abbreviation for the CLI type System.Collections.Generic.IEnumerable<_> type seq<'T> = IEnumerable<'T> - - namespace Microsoft.FSharp.Core open System diff --git a/src/fsharp/FSharp.Core/seq.fs b/src/fsharp/FSharp.Core/seq.fs index b7334d6eaf7..c23c36dc138 100644 --- a/src/fsharp/FSharp.Core/seq.fs +++ b/src/fsharp/FSharp.Core/seq.fs @@ -1068,7 +1068,7 @@ namespace Microsoft.FSharp.Collections 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 RuntimeHelpers.StructBox<'Key>.Comparer (fun t -> RuntimeHelpers.StructBox (keyf t)) (fun sb -> sb.Value) + 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>) = @@ -1151,7 +1151,7 @@ namespace Microsoft.FSharp.Collections 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 RuntimeHelpers.StructBox<'Key>.Comparer (fun t -> RuntimeHelpers.StructBox (keyf t)) (fun sb -> sb.Value) + 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>) = diff --git a/src/fsharp/FSharp.Core/seqcore.fs b/src/fsharp/FSharp.Core/seqcore.fs index e733d7f9a2d..b9e94bee755 100644 --- a/src/fsharp/FSharp.Core/seqcore.fs +++ b/src/fsharp/FSharp.Core/seqcore.fs @@ -135,6 +135,820 @@ namespace Microsoft.FSharp.Collections interface IEnumerable with member x.GetEnumerator() = (f() :> IEnumerator) } +namespace Microsoft.FSharp.Collections.SeqComposition + open System + open System.Collections + open System.Collections.Generic + open Microsoft.FSharp.Core + open Microsoft.FSharp.Collections + open Microsoft.FSharp.Collections.IEnumerator + open Microsoft.FSharp.Collections.SeqComposition + open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators + open Microsoft.FSharp.Primitives.Basics + open Microsoft.FSharp.Control + + module Core = + [] + type NoValue = struct end + + 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 Closure = + // F# inlines simple functions, which can mean that it some case you keep creating closures when + // a single funciton object would have done. This forces the compiler to create the object + let inline forceCapture<'a,'b> (f:'a->'b) : 'a->'b = (# "" f : 'a->'b #) + + type IdentityFactory<'T> private () = + static let singleton : ITransformFactory<'T,'T> = upcast (IdentityFactory<'T>()) + static member Instance = singleton + interface ITransformFactory<'T,'T> with + member __.Compose<'V> (_outOfBand:IOutOfBand) (_pipeIdx:PipeIdx) (next:Activity<'T,'V>) : Activity<'T,'V> = next + + type ComposedFactory<'T,'U,'V> private (first:ITransformFactory<'T,'U>, second:ITransformFactory<'U,'V>) = + interface ITransformFactory<'T,'V> with + member 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:ITransformFactory<'T,'U>) (second:ITransformFactory<'U,'V>) : ITransformFactory<'T,'V> = + upcast ComposedFactory(first, second) + + type ISkipable = + // Seq.init(Infinite)? lazily uses Current. The only ISeq 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 EmptyEnumerator<'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 EmptyEnumerator<'T> ()) + static member Element = element + + [] + type EnumerableBase<'T> () = + let derivedClassShouldImplement () = + failwith "library implementation error: derived class should implement (should be abstract)" + + abstract member Append : ISeq<'T> -> ISeq<'T> + abstract member Length : unit -> int + abstract member GetRaw : unit -> seq<'T> + + default this.Append source = upcast (AppendEnumerable [source; this]) + default this.Length () = Microsoft.FSharp.Primitives.Basics.ISeq.length this + default this.GetRaw () = upcast this + + interface IEnumerable with + member this.GetEnumerator () : IEnumerator = + upcast ((this:>IEnumerable<'T>).GetEnumerator ()) + + interface IEnumerable<'T> with + // fsharp doesn't allow abstract interface methods + member this.GetEnumerator () : IEnumerator<'T> = derivedClassShouldImplement () + + interface ISeq<'T> with + // fsharp doesn't allow abstract interface methods + member __.PushTransform _ = derivedClassShouldImplement () + member __.Fold _ = derivedClassShouldImplement () + + and [] SeqFactoryBase<'T,'U>(transformFactory:ITransformFactory<'T,'U>, pipeIdx:PipeIdx) = + inherit EnumerableBase<'U>() + + member __.CreateActivityPipeline<'Result> (folder:Folder<'U,'Result>) : Activity<'T,'U> = + transformFactory.Compose (folder :> IOutOfBand) pipeIdx folder + + member this.CreatePipeline<'Result> (createFolder:PipeIdx->Folder<'U,'Result>, [] activity:byref>) = + let folder = createFolder (pipeIdx+1) + activity <- this.CreateActivityPipeline folder + folder + + member __.Compose next = ComposedFactory.Combine transformFactory next + + member __.PipeIdx = pipeIdx + + and [] EnumeratorBase<'T>() = + inherit Folder<'T,'T>(Unchecked.defaultof<'T>) + + member val SeqState = SeqProcessNextStates.NotStarted with get, set + abstract Activity : Activity + + override this.ProcessNext (input:'T) : bool = + this.Result <- input + true + + interface IDisposable with + member this.Dispose () : unit = + this.Activity.ChainDispose () + + interface IEnumerator with + member this.Current : obj = box (this :> IEnumerator<'T>).Current + member __.MoveNext () = failwith "library implementation error: derived class should implement (should be abstract)" + member __.Reset () : unit = noReset () + + interface IEnumerator<'T> with + member this.Current = + if this.SeqState = SeqProcessNextStates.InProcess then this.Result + else + match this.SeqState with + | SeqProcessNextStates.NotStarted -> notStarted() + | SeqProcessNextStates.Finished -> alreadyFinished() + | _ -> failwith "library implementation error: all states should have been handled" + + and VanillaEnumerator<'T,'U> private (source:IEnumerator<'T>) = + inherit EnumeratorBase<'U>() + + let mutable activity = Unchecked.defaultof> + + member __.FinaliseConstruct(activity':Activity<'T,'U>) = + activity <- activity' + + override this.Activity = upcast activity + + member private this.MoveNext () = + if this.HaltedIdx = 0 && source.MoveNext () then + if activity.ProcessNext source.Current then + true + else + this.MoveNext () + else + this.SeqState <- SeqProcessNextStates.Finished + activity.ChainComplete this.HaltedIdx + false + + interface IEnumerator with + member this.MoveNext () = + this.SeqState <- SeqProcessNextStates.InProcess + this.MoveNext () + + interface IDisposable with + member __.Dispose () = + try + source.Dispose () + finally + activity.ChainDispose () + + static member Construct (source:IEnumerator<'T>) (factory:SeqFactoryBase<'T,'U>) : IEnumerator<'U> = + let enumerator = new VanillaEnumerator<'T,'U>(source) + enumerator.FinaliseConstruct (factory.CreateActivityPipeline enumerator) + upcast enumerator + + and VanillaEnumerable<'T,'U>(enumerable:IEnumerable<'T>, transformFactory:ITransformFactory<'T,'U>, pipeIdx:PipeIdx) = + inherit SeqFactoryBase<'T,'U>(transformFactory, pipeIdx) + + interface IEnumerable<'U> with + member this.GetEnumerator () = VanillaEnumerator<'T,'U>.Construct (enumerable.GetEnumerator()) this + + interface ISeq<'U> with + member this.PushTransform (next:ITransformFactory<'U,'V>) : ISeq<'V> = + upcast (new VanillaEnumerable<'T,'V>(enumerable, this.Compose next, this.PipeIdx+1)) + + member this.Fold<'Result> (createFolder:PipeIdx->Folder<'U,'Result>) = + let result, consumer = this.CreatePipeline createFolder + try + use enumerator = enumerable.GetEnumerator () + while result.HaltedIdx = 0 && enumerator.MoveNext () do + consumer.ProcessNext enumerator.Current |> ignore + + consumer.ChainComplete result.HaltedIdx + finally + consumer.ChainDispose () + result.Result + + and ConcatCommon<'T>(consumer:Activity<'T>) = + inherit Folder<'T,NoValue>(Unchecked.defaultof<_>) + + member __.Consumer = consumer + + override me.ProcessNext value = TailCall.avoid (consumer.ProcessNext value) + + and ConcatFold<'T,'U,'Collection,'Result when 'Collection :> ISeq<'T>>(result:Folder<'U,'Result>, consumer:Activity<'T,'U>, common:Folder<'T,NoValue>) as this = + inherit Folder<'Collection, 'Result>(Unchecked.defaultof<_>) + + do + (this :> IOutOfBand).ListenForStopFurtherProcessing (fun idx -> + (result :> IOutOfBand).StopFurtherProcessing idx + (common :> IOutOfBand).StopFurtherProcessing PipeIdx.MinValue) + + (result :> IOutOfBand).ListenForStopFurtherProcessing (fun idx -> + (this :> IOutOfBand).StopFurtherProcessing idx + (common :> IOutOfBand).StopFurtherProcessing PipeIdx.MaxValue) + + let getCommonFolder = Closure.forceCapture (fun (_:PipeIdx) -> + (common :> IOutOfBand).StopFurtherProcessing 0 + common) + + override __.ProcessNext value = + value.Fold getCommonFolder |> ignore + Unchecked.defaultof<_> (* return value unused in Fold context *) + + override this.ChainComplete _ = + consumer.ChainComplete result.HaltedIdx + this.Result <- result.Result + + override this.ChainDispose () = + consumer.ChainDispose () + + and ConcatEnumerator<'T,'U,'Collection when 'Collection :> IEnumerable<'T>> private (sources:IEnumerable<'Collection>) = + inherit EnumeratorBase<'U>() + + let main = sources.GetEnumerator () + let mutable active = EmptyEnumerators.Element + let mutable activity = Unchecked.defaultof> + + override this.Activity = upcast activity + + member __.FinaliseConstruct(activity':Activity<'T,'U>) = + activity <- activity' + + member private this.MoveNext () = + if this.HaltedIdx <> 0 then false + else + if active.MoveNext () then + if activity.ProcessNext active.Current then + true + else + this.MoveNext () + elif main.MoveNext () then + active.Dispose () + active <- main.Current.GetEnumerator () + this.MoveNext () + else + this.SeqState <- SeqProcessNextStates.Finished + activity.ChainComplete this.HaltedIdx + false + + interface IEnumerator with + member this.MoveNext () = + this.SeqState <- SeqProcessNextStates.InProcess + this.MoveNext () + + interface IDisposable with + member __.Dispose () = + try + main.Dispose () + active.Dispose () + finally + activity.ChainDispose () + + static member Construct (sources:IEnumerable<'Collection>) (factory:SeqFactoryBase<'T,'U>) : IEnumerator<'U> = + let enumerator = new ConcatEnumerator<'T,'U,'Collection>(sources) + enumerator.FinaliseConstruct (factory.CreateActivityPipeline enumerator) + upcast enumerator + + and ConcatEnumerable<'T,'U,'Collection when 'Collection :> ISeq<'T>> (sources:ISeq<'Collection>, transformFactory:ITransformFactory<'T,'U>, pipeIdx:PipeIdx) = + inherit SeqFactoryBase<'T,'U>(transformFactory, pipeIdx) + + interface IEnumerable<'U> with + member this.GetEnumerator () = ConcatEnumerator<'T,'U,'Collection>.Construct sources this + + interface ISeq<'U> with + member this.PushTransform (next:ITransformFactory<'U,'V>) : ISeq<'V> = + upcast (new ConcatEnumerable<'T,'V,'Collection>(sources, this.Compose next, this.PipeIdx+1)) + + member this.Fold<'Result> (createFolder:PipeIdx->Folder<'U,'Result>) = + sources.Fold (fun lowerPipeIdx -> + let thisPipeIdx = lowerPipeIdx + pipeIdx + + let result = createFolder (thisPipeIdx+1) + + let outOfBand = result :> IOutOfBand + + let consumer = transformFactory.Compose outOfBand thisPipeIdx result + + let common = + match box consumer with + | :? ConcatCommon<'T> as c -> ConcatCommon c.Consumer + | _ -> ConcatCommon consumer + + upcast ConcatFold (result, consumer, common)) + + and ThinConcatEnumerable<'T, 'Sources, 'Collection when 'Collection :> ISeq<'T>> (sources:'Sources, preEnumerate:'Sources->ISeq<'Collection>) = + inherit EnumerableBase<'T>() + + member private __.Fatten : ISeq<'T> = upcast (ConcatEnumerable<'T,'T,'Collection>(preEnumerate sources, IdentityFactory.Instance, 1)) + + interface IEnumerable<'T> with + member this.GetEnumerator () = this.Fatten.GetEnumerator () + + interface ISeq<'T> with + member this.PushTransform (next:ITransformFactory<'T,'U>) : ISeq<'U> = + upcast (ConcatEnumerable<'T,'V,'Collection>(preEnumerate sources, next, 1)) + + member this.Fold<'Result> (createFolder:PipeIdx->Folder<'T,'Result>) = + this.Fatten.Fold createFolder + + and AppendEnumerable<'T> (sources:list>) = + inherit ThinConcatEnumerable<'T, list>, ISeq<'T>>(sources, fun sources -> upcast (List.rev sources)) + + override this.Append source = + upcast (AppendEnumerable (source::sources)) + + /// ThinEnumerable is used when the IEnumerable provided to ofSeq is neither an array or a list + type ThinEnumerable<'T>(enumerable:IEnumerable<'T>) = + inherit VanillaEnumerable<'T,'T>(enumerable, IdentityFactory.Instance, 0) + + override __.Length () = + match enumerable with + | :? ICollection<'T> as a -> a.Count +#if !FSCORE_PORTABLE_OLD + | :? IReadOnlyCollection<'T> as a -> a.Count +#endif + | _ -> + use e = enumerable.GetEnumerator () + let mutable count = 0 + while e.MoveNext () do + count <- count + 1 + count + + interface IEnumerable<'T> with + member __.GetEnumerator () = enumerable.GetEnumerator () + + type DelayedEnumerable<'T>(delayed:unit->ISeq<'T>, pipeIdx:PipeIdx) = + inherit EnumerableBase<'T>() + + override __.Length () = + match delayed() with + | :? EnumerableBase<'T> as s -> s.Length () + | s -> Microsoft.FSharp.Primitives.Basics.ISeq.length s + + override __.GetRaw () = + match delayed() with + | :? EnumerableBase<'T> as s -> s.GetRaw () + | s -> upcast s + + interface IEnumerable<'T> with + member this.GetEnumerator () : IEnumerator<'T> = (delayed()).GetEnumerator () + + interface ISeq<'T> with + member __.PushTransform (next:ITransformFactory<'T,'U>) : ISeq<'U> = + upcast (new DelayedEnumerable<'U>((fun () -> (delayed()).PushTransform next), pipeIdx+1)) + + member __.Fold<'Result> (f:PipeIdx->Folder<'T,'Result>) = + (delayed()).Fold f + + type EmptyEnumerable<'T> private () = + inherit EnumerableBase<'T>() + + static let singleton = EmptyEnumerable<'T>() :> ISeq<'T> + static member Instance = singleton + + override __.Length () = 0 + + interface IEnumerable<'T> with + member this.GetEnumerator () : IEnumerator<'T> = IEnumerator.Empty<'T>() + + override this.Append source = source + + interface ISeq<'T> with + member this.PushTransform (next:ITransformFactory<'T,'U>) : ISeq<'U> = + upcast (VanillaEnumerable<'T,'V>(this, next, 1)) + + member this.Fold<'Result> (createFolder:PipeIdx->Folder<'T,'Result>) = + let result = createFolder 1 + try + result.ChainComplete result.HaltedIdx + finally + result.ChainDispose () + result.Result + + type ArrayEnumerator<'T,'U> private (array:array<'T>) = + inherit EnumeratorBase<'U>() + + let mutable idx = 0 + let mutable activity = Unchecked.defaultof> + + member __.FinaliseConstruct(activity':Activity<'T,'U>) = + activity <- activity' + + override this.Activity = upcast activity + + member private this.MoveNext () = + if this.HaltedIdx = 0 && idx < array.Length then + idx <- idx+1 + if activity.ProcessNext array.[idx-1] then + true + else + this.MoveNext () + else + this.SeqState <- SeqProcessNextStates.Finished + activity.ChainComplete this.HaltedIdx + false + + interface IEnumerator with + member this.MoveNext () = + this.SeqState <- SeqProcessNextStates.InProcess + this.MoveNext () + + static member Construct (array:array<'T>) (factory:SeqFactoryBase<'T,'U>) : IEnumerator<'U> = + let enumerator = new ArrayEnumerator<'T,'U>(array) + enumerator.FinaliseConstruct (factory.CreateActivityPipeline enumerator) + upcast enumerator + + type ArrayEnumerable<'T,'U>(array:array<'T>, transformFactory:ITransformFactory<'T,'U>, pipeIdx:PipeIdx) = + inherit SeqFactoryBase<'T,'U>(transformFactory, pipeIdx) + + interface IEnumerable<'U> with + member this.GetEnumerator () = ArrayEnumerator<'T,'U>.Construct array this + + interface ISeq<'U> with + member this.PushTransform (next:ITransformFactory<'U,'V>) : ISeq<'V> = + upcast (new ArrayEnumerable<'T,'V>(array, this.Compose next, this.PipeIdx+1)) + + member this.Fold<'Result> (createFolder:PipeIdx->Folder<'U,'Result>) = + let result, consumer = this.CreatePipeline createFolder + try + let array = array + let mutable idx = 0 + while result.HaltedIdx = 0 && idx < array.Length do + consumer.ProcessNext array.[idx] |> ignore + idx <- idx + 1 + + consumer.ChainComplete result.HaltedIdx + finally + consumer.ChainDispose () + result.Result + + type ThinArrayEnumerable<'T>(array:array<'T>) = + inherit ArrayEnumerable<'T,'T>(array, IdentityFactory.Instance, 0) + + override __.Length () = array.Length + override __.GetRaw () = upcast array + + interface IEnumerable<'T> with + member __.GetEnumerator () = (array:>IEnumerable<'T>).GetEnumerator () + + type SingletonEnumerable<'T>(item:'T) = + inherit EnumerableBase<'T>() + + override __.Length () = 1 + + interface IEnumerable<'T> with + member this.GetEnumerator () = (new Singleton<'T>(item)) :> IEnumerator<'T> + + interface ISeq<'T> with + member __.PushTransform (next:ITransformFactory<'T,'U>) : ISeq<'U> = + ([item] :> ISeq<'T>).PushTransform next + + member this.Fold<'Result> (createFolder:PipeIdx->Folder<'T,'Result>) = + let result = createFolder 1 + try + if result.HaltedIdx = 0 then + result.ProcessNext item |> ignore + + result.ChainComplete result.HaltedIdx + finally + result.ChainDispose () + result.Result + + type ResizeArrayEnumerator<'T,'U> private (array:ResizeArray<'T>) = + inherit EnumeratorBase<'U>() + + let mutable idx = 0 + let mutable activity = Unchecked.defaultof> + + member __.FinaliseConstruct(activity':Activity<'T,'U>) = + activity <- activity' + + override this.Activity = upcast activity + + member private this.MoveNext () = + if this.HaltedIdx = 0 && idx < array.Count then + idx <- idx+1 + if activity.ProcessNext array.[idx-1] then + true + else + this.MoveNext () + else + this.SeqState <- SeqProcessNextStates.Finished + activity.ChainComplete this.HaltedIdx + false + + interface IEnumerator with + member this.MoveNext () = + this.SeqState <- SeqProcessNextStates.InProcess + this.MoveNext () + + static member Construct (array:ResizeArray<'T>) (factory:SeqFactoryBase<'T,'U>) : IEnumerator<'U> = + let enumerator = new ResizeArrayEnumerator<'T,'U>(array) + enumerator.FinaliseConstruct (factory.CreateActivityPipeline enumerator) + upcast enumerator + + type ResizeArrayEnumerable<'T,'U>(resizeArray:ResizeArray<'T>, transformFactory:ITransformFactory<'T,'U>, pipeIdx:PipeIdx) = + inherit SeqFactoryBase<'T,'U>(transformFactory, pipeIdx) + + interface IEnumerable<'U> with + member this.GetEnumerator () = ResizeArrayEnumerator<'T,'U>.Construct resizeArray this + + interface ISeq<'U> with + member this.PushTransform (next:ITransformFactory<'U,'V>) : ISeq<'V> = + upcast (new ResizeArrayEnumerable<'T,'V>(resizeArray, this.Compose next, this.PipeIdx+1)) + + member this.Fold<'Result> (createFolder:PipeIdx->Folder<'U,'Result>) = + let result, consumer = this.CreatePipeline createFolder + try + let array = resizeArray + let mutable idx = 0 + while result.HaltedIdx = 0 && idx < array.Count do + consumer.ProcessNext array.[idx] |> ignore + idx <- idx + 1 + + consumer.ChainComplete result.HaltedIdx + finally + consumer.ChainDispose () + result.Result + + type ThinResizeArrayEnumerable<'T>(resizeArray:ResizeArray<'T>) = + inherit ResizeArrayEnumerable<'T,'T>(resizeArray, IdentityFactory.Instance, 0) + + override __.Length () = resizeArray.Count + + type UnfoldEnumerator<'T,'U,'State> private (generator:'State->option<'T*'State>, state:'State) = + inherit EnumeratorBase<'U>() + + let mutable current = state + + let mutable activity = Unchecked.defaultof> + + member __.FinaliseConstruct(activity':Activity<'T,'U>) = + activity <- activity' + + override this.Activity = upcast activity + + member private this.MoveNext () = + if this.HaltedIdx <> 0 then + false + else + match generator current with + | Some (item, nextState) -> + current <- nextState + if activity.ProcessNext item then + true + else + this.MoveNext () + | _ -> false + + interface IEnumerator with + member this.MoveNext () = + this.SeqState <- SeqProcessNextStates.InProcess + this.MoveNext () + + static member Construct (generator:'State->option<'T*'State>) (state:'State) (factory:SeqFactoryBase<'T,'U>) : IEnumerator<'U> = + let enumerator = new UnfoldEnumerator<'T,'U,'State>(generator, state) + enumerator.FinaliseConstruct (factory.CreateActivityPipeline enumerator) + upcast enumerator + + type UnfoldEnumerable<'T,'U,'GeneratorState>(generator:'GeneratorState->option<'T*'GeneratorState>, state:'GeneratorState, transformFactory:ITransformFactory<'T,'U>, pipeIdx:PipeIdx) = + inherit SeqFactoryBase<'T,'U>(transformFactory, pipeIdx) + + interface IEnumerable<'U> with + member this.GetEnumerator () = UnfoldEnumerator<'T,'U,'GeneratorState>.Construct generator state this + + interface ISeq<'U> with + member this.PushTransform (next:ITransformFactory<'U,'V>) : ISeq<'V> = + upcast (new UnfoldEnumerable<'T,'V,'GeneratorState>(generator, state, this.Compose next, this.PipeIdx+1)) + + member this.Fold<'Result> (createFolder:PipeIdx->Folder<'U,'Result>) = + let result, consumer = this.CreatePipeline createFolder + try + let generator = generator + let rec iterate current = + if result.HaltedIdx <> 0 then () + else + match generator current with + | Some (item, next) -> + consumer.ProcessNext item |> ignore + iterate next + | _ -> () + iterate state + + consumer.ChainComplete result.HaltedIdx + finally + consumer.ChainDispose () + result.Result + + let getInitTerminatingIdx (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 InitEnumerator<'T,'U>(count:Nullable, f:int->'T) = + inherit EnumeratorBase<'U>() + + let terminatingIdx = + getInitTerminatingIdx count + + let mutable maybeSkipping = true + let mutable idx = -1 + + let mutable activity = Unchecked.defaultof> + let mutable isSkipping = Unchecked.defaultofbool> + + member __.FinaliseConstruct(activity':Activity<'T,'U>) = + activity <- activity' + + isSkipping <- + match box activity with + | :? ISkipable as skip -> skip.CanSkip + | _ -> fun () -> false + + + override this.Activity = upcast activity + + member private this.MoveNext () = + if this.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 + this.MoveNext () + elif activity.ProcessNext (f idx) then + true + else + this.MoveNext () + elif this.HaltedIdx = 0 && idx = System.Int32.MaxValue then + raise <| System.InvalidOperationException (SR.GetString(SR.enumerationPastIntMaxValue)) + else + this.SeqState <- SeqProcessNextStates.Finished + activity.ChainComplete this.HaltedIdx + false + + interface IEnumerator with + member this.MoveNext () = + this.SeqState <- SeqProcessNextStates.InProcess + this.MoveNext () + + static member Construct (count:Nullable) (f:int->'T) (factory:SeqFactoryBase<'T,'U>) : IEnumerator<'U> = + let enumerator = new InitEnumerator<'T,'U>(count, f) + enumerator.FinaliseConstruct (factory.CreateActivityPipeline enumerator) + upcast enumerator + + type InitEnumerable<'T,'U>(count:Nullable, f:int->'T, transformFactory:ITransformFactory<'T,'U>, pipeIdx:PipeIdx) = + inherit SeqFactoryBase<'T,'U>(transformFactory, pipeIdx) + + interface IEnumerable<'U> with + member this.GetEnumerator () = InitEnumerator<'T,'U>.Construct count f this + + interface ISeq<'U> with + member this.PushTransform (next:ITransformFactory<'U,'V>) : ISeq<'V> = + upcast (new InitEnumerable<'T,'V>(count, f, this.Compose next, this.PipeIdx+1)) + + member this.Fold<'Result> (createFolder:PipeIdx->Folder<'U,'Result>) = + let terminatingIdx = getInitTerminatingIdx count + let result, consumer = this.CreatePipeline createFolder + try + let firstIdx = + match box consumer with + | :? ISkipable as skipping -> + let rec skip idx = + if idx = terminatingIdx || result.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 result.HaltedIdx = 0 then + iterate (idx+1) + else + idx + else + idx + + let finalIdx = iterate firstIdx + if result.HaltedIdx = 0 && finalIdx = System.Int32.MaxValue then + raise <| System.InvalidOperationException (SR.GetString(SR.enumerationPastIntMaxValue)) + + consumer.ChainComplete result.HaltedIdx + finally + consumer.ChainDispose () + result.Result + + // 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. + // InitEnumerableDecider returns the original implementation of init when GetEnumerator is called + // If any Activites are added to the pipeline then the original implementation is ignored, as special + // handling has been added to Current isn't calculated whilst skipping enumerated items. + type InitEnumerableDecider<'T>(count:Nullable, f:int->'T, pipeIdx:PipeIdx) = + inherit EnumerableBase<'T>() + + 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 () = () } + + override this.Length () = + if count.HasValue then + count.Value + else + raise (System.InvalidOperationException (SR.GetString(SR.enumerationPastIntMaxValue))) + + 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:ITransformFactory<'T,'U>) : ISeq<'U> = + upcast (InitEnumerable<'T,'V>(count, f, next, pipeIdx+1)) + + member this.Fold<'Result> (createFolder:PipeIdx->Folder<'T,'Result>) = + let result = createFolder 1 + try + use enumerator = (this:>IEnumerable<'T>).GetEnumerator () + while result.HaltedIdx = 0 && enumerator.MoveNext () do + result.ProcessNext enumerator.Current |> ignore + + result.ChainComplete result.HaltedIdx + finally + result.ChainDispose () + result.Result + namespace Microsoft.FSharp.Core.CompilerServices open System @@ -148,18 +962,10 @@ namespace Microsoft.FSharp.Core.CompilerServices open Microsoft.FSharp.Primitives.Basics open System.Collections open System.Collections.Generic + open Microsoft.FSharp.Collections.SeqComposition + open Microsoft.FSharp.Collections.SeqComposition.Core 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) @@ -354,9 +1160,13 @@ namespace Microsoft.FSharp.Core.CompilerServices [] type GeneratedSequenceBase<'T>() = + inherit EnumerableBase<'T>() + let mutable redirectTo : GeneratedSequenceBase<'T> = Unchecked.defaultof<_> let mutable redirect : bool = false + member internal x.GetCurrent () = if redirect then redirectTo.LastGenerated else x.LastGenerated + abstract GetFreshEnumerator : unit -> IEnumerator<'T> abstract GenerateNext : next:byref> -> int // 0 = Stop, 1 = Yield, 2 = Goto abstract Close: unit -> unit @@ -394,7 +1204,7 @@ namespace Microsoft.FSharp.Core.CompilerServices 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.Current = x.GetCurrent () 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) @@ -403,3 +1213,64 @@ namespace Microsoft.FSharp.Core.CompilerServices member x.MoveNext() = x.MoveNextImpl() member x.Reset() = raise <| new System.NotSupportedException() + + interface ISeq<'T> with + member this.PushTransform<'U> (next:ITransformFactory<'T,'U>) : ISeq<'U> = + upcast (new GeneratedSequenceBaseEnumerable<'T,'U>(this, next, 1)) + + member this.Fold<'Result> (createFolder:PipeIdx->Folder<'T,'Result>) = + let result = createFolder 1 + try + use maybeGeneratedSequenceBase = this.GetFreshEnumerator () + match maybeGeneratedSequenceBase with + | :? GeneratedSequenceBase<'T> as e -> // avoids two virtual function calls + while result.HaltedIdx = 0 && e.MoveNextImpl () do + result.ProcessNext (e.GetCurrent ()) |> ignore + | e -> + while result.HaltedIdx = 0 && e.MoveNext () do + result.ProcessNext e.Current |> ignore + + result.ChainComplete result.HaltedIdx + finally + result.ChainDispose () + result.Result + + override this.Length () = + use maybeGeneratedSequenceBase = this.GetFreshEnumerator () + let mutable count = 0 + match maybeGeneratedSequenceBase with + | :? GeneratedSequenceBase<'T> as e -> + while e.MoveNextImpl () do + count <- count + 1 + | e -> + while e.MoveNext () do + count <- count + 1 + count + + and GeneratedSequenceBaseEnumerable<'T,'U>(generatedSequence:GeneratedSequenceBase<'T>, transformFactory:ITransformFactory<'T,'U>, pipeIdx:PipeIdx) = + inherit SeqFactoryBase<'T,'U>(transformFactory, pipeIdx) + + interface IEnumerable<'U> with + member this.GetEnumerator () = VanillaEnumerator<'T,'U>.Construct (generatedSequence.GetFreshEnumerator()) this + + interface ISeq<'U> with + member this.PushTransform (next:ITransformFactory<'U,'V>) : ISeq<'V> = + upcast (new GeneratedSequenceBaseEnumerable<'T,'V>(generatedSequence, this.Compose next, this.PipeIdx+1)) + + member this.Fold<'Result> (createFolder:PipeIdx->Folder<'U,'Result>) = + let result, consumer = this.CreatePipeline createFolder + try + use maybeGeneratedSequenceBase = generatedSequence.GetFreshEnumerator () + match maybeGeneratedSequenceBase with + | :? GeneratedSequenceBase<'T> as e -> + while result.HaltedIdx = 0 && e.MoveNextImpl () do + consumer.ProcessNext (e.GetCurrent ()) |> ignore + | e -> + while result.HaltedIdx = 0 && e.MoveNext () do + consumer.ProcessNext e.Current |> ignore + + consumer.ChainComplete result.HaltedIdx + finally + consumer.ChainDispose () + result.Result + diff --git a/src/fsharp/FSharp.Core/seqcore.fsi b/src/fsharp/FSharp.Core/seqcore.fsi index ebd7accb8e5..ec6ef0f2881 100644 --- a/src/fsharp/FSharp.Core/seqcore.fsi +++ b/src/fsharp/FSharp.Core/seqcore.fsi @@ -55,6 +55,115 @@ namespace Microsoft.FSharp.Collections f:(unit -> System.Collections.Generic.IEnumerator<'U>) -> System.Collections.Generic.IEnumerable<'U> + +namespace Microsoft.FSharp.Collections.SeqComposition + open System + open System.Collections + open System.Collections.Generic + open Microsoft.FSharp.Core + open Microsoft.FSharp.Collections + open Microsoft.FSharp.Collections.SeqComposition + + module Core = + [] + type NoValue = struct end + + [] + type internal EnumerableBase<'T> = + new : unit -> EnumerableBase<'T> + abstract member Append : ISeq<'T> -> ISeq<'T> + abstract member Length : unit -> int + abstract member GetRaw : unit -> seq<'T> + default Append : ISeq<'T> -> ISeq<'T> + default Length : unit -> int + default GetRaw : unit -> seq<'T> + interface ISeq<'T> + + [] + type internal SeqFactoryBase<'T,'U> = + inherit EnumerableBase<'U> + new : ITransformFactory<'T,'U> * PipeIdx -> SeqFactoryBase<'T,'U> + + [] + type internal IdentityFactory<'T> = + interface ITransformFactory<'T,'T> + static member Instance : ITransformFactory<'T,'T> + + type internal ISkipable = + // Seq.init(Infinite)? lazily uses Current. The only ISeq component that can do that is Skip + // and it can only do it at the start of a sequence + abstract CanSkip : unit -> bool + + type internal ThinConcatEnumerable<'T, 'Sources, 'Collection when 'Collection :> ISeq<'T>> = + inherit EnumerableBase<'T> + new : 'Sources * ('Sources->ISeq<'Collection>) -> ThinConcatEnumerable<'T, 'Sources, 'Collection> + interface ISeq<'T> + + type internal AppendEnumerable<'T> = + inherit ThinConcatEnumerable<'T, list>, ISeq<'T>> + new : list> -> AppendEnumerable<'T> + override Append : ISeq<'T> -> ISeq<'T> + + type internal ResizeArrayEnumerable<'T,'U> = + inherit SeqFactoryBase<'T,'U> + new : ResizeArray<'T> * ITransformFactory<'T,'U> * PipeIdx -> ResizeArrayEnumerable<'T,'U> + interface ISeq<'U> + + type internal ThinResizeArrayEnumerable<'T> = + inherit ResizeArrayEnumerable<'T,'T> + new : ResizeArray<'T> -> ThinResizeArrayEnumerable<'T> + + type internal ArrayEnumerable<'T,'U> = + inherit SeqFactoryBase<'T,'U> + new : array<'T> * ITransformFactory<'T,'U> * PipeIdx -> ArrayEnumerable<'T,'U> + interface ISeq<'U> + + type internal ThinArrayEnumerable<'T> = + inherit ArrayEnumerable<'T, 'T> + new : array<'T> -> ThinArrayEnumerable<'T> + interface IEnumerable<'T> + + type internal VanillaEnumerable<'T,'U> = + inherit SeqFactoryBase<'T,'U> + new : IEnumerable<'T> * ITransformFactory<'T,'U> * PipeIdx -> VanillaEnumerable<'T,'U> + interface ISeq<'U> + + type internal ThinEnumerable<'T> = + inherit VanillaEnumerable<'T,'T> + new : IEnumerable<'T> -> ThinEnumerable<'T> + interface IEnumerable<'T> + + type internal UnfoldEnumerable<'T,'U,'GeneratorState> = + inherit SeqFactoryBase<'T,'U> + new : ('GeneratorState->option<'T*'GeneratorState>)*'GeneratorState*ITransformFactory<'T,'U>*PipeIdx -> UnfoldEnumerable<'T,'U,'GeneratorState> + interface ISeq<'U> + + type internal InitEnumerableDecider<'T> = + inherit EnumerableBase<'T> + new : Nullable* (int->'T) * PipeIdx -> InitEnumerableDecider<'T> + interface ISeq<'T> + + type internal SingletonEnumerable<'T> = + inherit EnumerableBase<'T> + new : 'T -> SingletonEnumerable<'T> + interface ISeq<'T> + + type internal InitEnumerable<'T,'U> = + inherit SeqFactoryBase<'T,'U> + new : Nullable * (int->'T) * ITransformFactory<'T,'U> * PipeIdx -> InitEnumerable<'T,'U> + interface ISeq<'U> + + type internal DelayedEnumerable<'T> = + inherit EnumerableBase<'T> + new : (unit->ISeq<'T>) * PipeIdx -> DelayedEnumerable<'T> + interface ISeq<'T> + + type internal EmptyEnumerable<'T> = + inherit EnumerableBase<'T> + private new : unit -> EmptyEnumerable<'T> + static member Instance : ISeq<'T> + interface ISeq<'T> + namespace Microsoft.FSharp.Core.CompilerServices open System @@ -67,12 +176,6 @@ namespace Microsoft.FSharp.Core.CompilerServices /// 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> - val internal mkConcatSeq : sources:(seq<#seq<'T>>) -> seq<'T> /// The F# compiler emits calls to this function to @@ -124,6 +227,7 @@ namespace Microsoft.FSharp.Core.CompilerServices [] /// The F# compiler emits implementations of this type for compiled sequence expressions. type GeneratedSequenceBase<'T> = + inherit SeqComposition.Core.EnumerableBase<'T> /// The F# compiler emits implementations of this type for compiled sequence expressions. /// /// A new sequence generator for the expression. @@ -148,3 +252,4 @@ namespace Microsoft.FSharp.Core.CompilerServices interface IEnumerable interface IEnumerator<'T> interface IEnumerator + interface SeqComposition.ISeq<'T> diff --git a/src/fsharp/FSharp.Core/set.fs b/src/fsharp/FSharp.Core/set.fs index 6b31169c905..f33b27e1b5e 100644 --- a/src/fsharp/FSharp.Core/set.fs +++ b/src/fsharp/FSharp.Core/set.fs @@ -495,17 +495,9 @@ namespace Microsoft.FSharp.Collections let res = Array.zeroCreate n copyToArray s res 0; res - - - - let rec mkFromEnumerator comparer acc (e : IEnumerator<_>) = - if e.MoveNext() then - mkFromEnumerator comparer (add comparer e.Current acc) e - else acc let ofSeq comparer (c : IEnumerable<_>) = - use ie = c.GetEnumerator() - mkFromEnumerator comparer SetEmpty ie + Seq.fold (fun acc k -> add comparer k acc) SetEmpty c let ofArray comparer l = Array.fold (fun acc k -> add comparer k acc) SetEmpty l @@ -849,7 +841,6 @@ namespace Microsoft.FSharp.Collections [] let ofSeq (c : seq<_>) = new Set<_>(c) - [] let difference (s1: Set<'T>) (s2: Set<'T>) = s1 - s2 diff --git a/tests/fsharpqa/Source/Misc/LongSourceFile01.fs b/tests/fsharpqa/Source/Misc/LongSourceFile01.fs index 970a5f77ff6..d35f290ee73 100644 --- a/tests/fsharpqa/Source/Misc/LongSourceFile01.fs +++ b/tests/fsharpqa/Source/Misc/LongSourceFile01.fs @@ -247,6 +247,194 @@ Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityC Microsoft.FSharp.Collections.HashIdentity: System.Collections.Generic.IEqualityComparer`1[T] Structural[T]() Microsoft.FSharp.Collections.HashIdentity: System.String ToString() Microsoft.FSharp.Collections.HashIdentity: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Int32 HaltedIdx +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Int32 get_HaltedIdx() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: TResult Result +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: TResult get_Result() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: TState State +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void .ctor(TResult, TState) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void ChainDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void OnDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState]: Void set_Result(TResult) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Int32 HaltedIdx +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Int32 get_HaltedIdx() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: TResult Result +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: TResult get_Result() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: TState State +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Void .ctor(TResult, TState) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Void ChainDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState]: Void set_Result(TResult) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: TState State +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Void .ctor(Microsoft.FSharp.Collections.SeqComposition.Activity, TState) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Void ChainDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Void OnComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState]: Void OnDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: TState State +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Void .ctor(Microsoft.FSharp.Collections.SeqComposition.Activity, TState) +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState]: Void ChainDispose() +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: Void .ctor(a) +Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a]: a _1 +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: Void .ctor(a, b) +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: a _1 +Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b]: b _2 +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: Void .ctor(a, b, c) +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: a _1 +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: b _2 +Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c]: c _3 +Microsoft.FSharp.Collections.ISeqModule+Core: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule+Core: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithPostProcessing`3[T,TResult,TState] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+FolderWithState`3[T,TResult,TState] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+TransformWithPostProcessing`3[T,TResult,TState] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+Transform`3[T,TResult,TState] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+Value`1[a] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+Values`2[a,b] +Microsoft.FSharp.Collections.ISeqModule+Core: Microsoft.FSharp.Collections.ISeqModule+Core+Values`3[a,b,c] +Microsoft.FSharp.Collections.ISeqModule+Core: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule+Core: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule: Boolean Contains[T](T, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.ISeqModule: Boolean Exists2[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,System.Boolean]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Boolean ForAll2[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,System.Boolean]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Boolean IsEmpty[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Int32 CompareWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Int32 FindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Int32 FindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Int32 GetHashCode() +Microsoft.FSharp.Collections.ISeqModule: Int32 Length[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.FSharpList`1[T] ToList[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.ISeqModule+Core +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[System.Int32,a]] Indexed[a](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[a]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[T,T]] Pairwise[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[T1,T2]] AllPairs[T1,T2](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T1], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T2]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[T1,T2]] Zip[T1,T2](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T1], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T2]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[TKey,Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]]] GroupByRef[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[TKey,Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]]] GroupByVal[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[TKey,System.Int32]] CountByRef[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`2[TKey,System.Int32]] CountByVal[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[System.Tuple`3[T1,T2,T3]] Zip3[T1,T2,T3](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T1], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T2], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T3]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult] Collect[T,TCollection,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TCollection], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TState] ScanBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], TState) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TState] Scan[TState,T](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T[]] ChunkBySize[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T[]] SplitInto[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T[]] Windowed[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Append[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Cache[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Cast[T](System.Collections.IEnumerable) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Concat[TCollection,T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TCollection]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Delay[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] DistinctBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Distinct[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Empty[T]() +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Except[T](System.Collections.Generic.IEnumerable`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] InitializeInfinite[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] OfArray[T](T[]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] OfList[T](Microsoft.FSharp.Collections.FSharpList`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] OfResizeArrayUnchecked[T](System.Collections.Generic.List`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] OfSeq[T](System.Collections.Generic.IEnumerable`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Permute[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.Int32], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Replicate[T](Int32, T) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Reverse[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Singleton[T](T) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] SkipWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Skip[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] SortByDescending[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] SortBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] SortDescending[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] SortWith[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int32]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Sort[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Tail[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] TakeWhile[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Take[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Truncate[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Unfold[TState,T](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[T,TState]]], TState) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[V] Map2[T,TResult,V](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,V]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[V] MapIndexed2[T,TResult,V](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,V]]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[W] Map3[T,TResult,V,W](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.FSharpFunc`2[V,W]]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[V]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[b] Choose[a,b](Microsoft.FSharp.Core.FSharpFunc`2[a,Microsoft.FSharp.Core.FSharpOption`1[b]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[a]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[b] MapIndexed[a,b](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[a,b]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[a]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndexBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryHead[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryItem[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Microsoft.FSharp.Core.FSharpOption`1[T] TryLast[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: System.String ToString() +Microsoft.FSharp.Collections.ISeqModule: System.Tuple`2[Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult],TState] MapFoldBack[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,System.Tuple`2[TResult,TState]]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], TState) +Microsoft.FSharp.Collections.ISeqModule: System.Tuple`2[Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult],TState] MapFold[T,TState,TResult](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,System.Tuple`2[TResult,TState]]], TState, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: System.Type GetType() +Microsoft.FSharp.Collections.ISeqModule: T Average[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T ExactlyOne[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T FindBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Find[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Head[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Item[T](Int32, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Last[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T MaxBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Max[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T MinBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Min[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T ReduceBack[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Reduce[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[T,T]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T Sum[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: TResult AverageBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: TResult Pick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: TResult SumBy[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: TState Fold2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,TState]]], TState, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T1], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T2]) +Microsoft.FSharp.Collections.ISeqModule: TState FoldBack2[T1,T2,TState](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T1], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T2], TState) +Microsoft.FSharp.Collections.ISeqModule: TState FoldBack[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], TState) +Microsoft.FSharp.Collections.ISeqModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: T[] ToArray[T](Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Void Iterate2[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Void IterateIndexed2[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Core.Unit]]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult]) +Microsoft.FSharp.Collections.ISeqModule: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ISeqModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) +Microsoft.FSharp.Collections.ListModule: Boolean Contains[T](T, Microsoft.FSharp.Collections.FSharpList`1[T]) Microsoft.FSharp.Collections.ListModule: Boolean Equals(System.Object) Microsoft.FSharp.Collections.ListModule: Boolean Exists2[T1,T2](Microsoft.FSharp.Core.FSharpFunc`2[T1,Microsoft.FSharp.Core.FSharpFunc`2[T2,System.Boolean]], Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2]) Microsoft.FSharp.Collections.ListModule: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], Microsoft.FSharp.Collections.FSharpList`1[T]) @@ -342,6 +530,56 @@ Microsoft.FSharp.Collections.MapModule: TResult Pick[TKey,T,TResult](Microsoft.F Microsoft.FSharp.Collections.MapModule: TState FoldBack[TKey,T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpFunc`2[TState,TState]]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T], TState) Microsoft.FSharp.Collections.MapModule: TState Fold[TKey,T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]]], TState, Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) Microsoft.FSharp.Collections.MapModule: Void Iterate[TKey,T](Microsoft.FSharp.Core.FSharpFunc`2[TKey,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Collections.FSharpMap`2[TKey,T]) +Microsoft.FSharp.Collections.SeqComposition.Activity: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Activity: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Activity: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Activity: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Activity: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.SeqComposition.Activity: Void ChainDispose() +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Void .ctor() +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.SeqComposition.Activity`1[T]: Void ChainDispose() +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Void .ctor() +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,TResult]: Void ChainDispose() +Microsoft.FSharp.Collections.SeqComposition.Core+NoValue: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Core+NoValue: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Core+NoValue: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Core+NoValue: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Core: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Core: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Core: Microsoft.FSharp.Collections.SeqComposition.Core+NoValue +Microsoft.FSharp.Collections.SeqComposition.Core: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Core: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Boolean Equals(System.Object) +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Boolean ProcessNext(T) +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Int32 GetHashCode() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Int32 HaltedIdx +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Int32 get_HaltedIdx() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: System.String ToString() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: System.Type GetType() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: TResult Result +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: TResult get_Result() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Void .ctor(TResult) +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Void ChainComplete(Int32) +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Void ChainDispose() +Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]: Void set_Result(TResult) +Microsoft.FSharp.Collections.SeqComposition.IOutOfBand: Void ListenForStopFurtherProcessing(System.Action`1[System.Int32]) +Microsoft.FSharp.Collections.SeqComposition.IOutOfBand: Void StopFurtherProcessing(Int32) +Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[TResult] PushTransform[TResult](Microsoft.FSharp.Collections.SeqComposition.ITransformFactory`2[T,TResult]) +Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]: TResult Fold[TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Collections.SeqComposition.Folder`2[T,TResult]]) +Microsoft.FSharp.Collections.SeqComposition.ITransformFactory`2[T,TResult]: Microsoft.FSharp.Collections.SeqComposition.Activity`2[T,V] Compose[V](Microsoft.FSharp.Collections.SeqComposition.IOutOfBand, Int32, Microsoft.FSharp.Collections.SeqComposition.Activity`2[TResult,V]) +Microsoft.FSharp.Collections.SeqModule: Boolean Contains[T](T, System.Collections.Generic.IEnumerable`1[T]) Microsoft.FSharp.Collections.SeqModule: Boolean Equals(System.Object) Microsoft.FSharp.Collections.SeqModule: Boolean Exists2[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 Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], System.Collections.Generic.IEnumerable`1[T]) @@ -787,7 +1025,10 @@ Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Boolean Equal Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Boolean get_CheckClose() Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Int32 GenerateNext(System.Collections.Generic.IEnumerable`1[T] ByRef) Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Int32 GetHashCode() +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Int32 Length() +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T] Append(Microsoft.FSharp.Collections.SeqComposition.ISeq`1[T]) Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: System.Collections.Generic.IEnumerator`1[T] GetFreshEnumerator() +Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: System.Collections.Generic.IEnumerable`1[T] GetRaw() Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: System.String ToString() Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: System.Type GetType() Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1[T]: T LastGenerated