@@ -11,13 +11,6 @@ type internal AsyncEnumStatus =
11
11
| WithCurrent
12
12
| AfterAll
13
13
14
- [<Struct>]
15
- type internal WhileKind =
16
- /// The item under test is included (or skipped) even when the predicate returns false
17
- | Inclusive
18
- /// The item under test is always excluded (or not skipped)
19
- | Exclusive
20
-
21
14
[<Struct>]
22
15
type internal TakeOrSkipKind =
23
16
/// use the Seq.take semantics, raises exception if not enough elements
@@ -813,7 +806,7 @@ module internal TaskSeqInternal =
813
806
814
807
| PredicateAsync asyncPredicate ->
815
808
let mutable predicateHolds = true
816
- while hasMore && predicateHolds do
809
+ while hasMore && predicateHolds do // TODO: check perf if `while!` is going to be better or equal
817
810
let! predicateIsTrue = asyncPredicate e.Current
818
811
if predicateIsTrue then
819
812
yield e.Current
@@ -828,51 +821,40 @@ module internal TaskSeqInternal =
828
821
yield e.Current
829
822
}
830
823
831
- let skipWhile whileKind predicate ( source : TaskSeq < _ >) =
824
+ let skipWhile isInclusive predicate ( source : TaskSeq < _ >) =
832
825
checkNonNull ( nameof source) source
833
826
834
827
taskSeq {
835
828
use e = source.GetAsyncEnumerator CancellationToken.None
829
+ let! notEmpty = e.MoveNextAsync()
830
+ let mutable hasMore = notEmpty
836
831
837
- match ! e.MoveNextAsync() with
838
- | false -> () // Nothing further to do, no matter what the rules are
839
- | true ->
840
-
841
- let exclusive =
842
- match whileKind with
843
- | Exclusive -> true
844
- | Inclusive -> false
845
-
846
- let mutable cont = true
847
-
848
- match predicate with
849
- | Predicate predicate -> // skipWhile(Inclusive)?
850
- while cont do
851
- if predicate e.Current then // spam -> skip
852
- let! hasAnother = e.MoveNextAsync()
853
- cont <- hasAnother
854
- else // Starting the ham
855
- if exclusive then
856
- yield e.Current // return the item as it does not meet the condition for skipping
832
+ match predicate with
833
+ | Predicate synchronousPredicate ->
834
+ while hasMore && synchronousPredicate e.Current do
835
+ // keep skipping
836
+ let! cont = e.MoveNextAsync()
837
+ hasMore <- cont
857
838
858
- while ! e.MoveNextAsync() do // propagate the rest
859
- yield e.Current
839
+ | PredicateAsync asyncPredicate ->
840
+ let mutable predicateHolds = true
841
+ while hasMore && predicateHolds do // TODO: check perf if `while!` is going to be better or equal
842
+ let! predicateIsTrue = asyncPredicate e.Current
843
+ if predicateIsTrue then
844
+ // keep skipping
845
+ let! cont = e.MoveNextAsync()
846
+ hasMore <- cont
860
847
861
- cont <- false
862
- | PredicateAsync predicate -> // skipWhile(Inclusive)?Async
863
- while cont do
864
- match ! predicate e.Current with
865
- | true ->
866
- let! hasAnother = e.MoveNextAsync()
867
- cont <- hasAnother
868
- | false -> // We're starting the ham
869
- if exclusive then
870
- yield e.Current // return the item as it does not meet the condition for skipping
848
+ predicateHolds <- predicateIsTrue
871
849
872
- while ! e.MoveNextAsync() do // propagate the rest
873
- yield e.Current
850
+ // "inclusive" means: always skip the item that we pulled, regardless of the result of applying the predicate
851
+ // and only stop thereafter. The non-inclusive versions, in contrast, do not skip the item under which the predicate is false.
852
+ if hasMore && not isInclusive then
853
+ yield e.Current // don't skip, unless inclusive
874
854
875
- cont <- false
855
+ // propagate the rest
856
+ while ! e.MoveNextAsync() do
857
+ yield e.Current
876
858
}
877
859
878
860
// Consider turning using an F# version of this instead?
0 commit comments