@@ -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,8 +806,10 @@ module internal TaskSeqInternal =
813
806
814
807
| PredicateAsync asyncPredicate ->
815
808
let mutable predicateHolds = true
816
- while hasMore && predicateHolds do
809
+
810
+ while hasMore && predicateHolds do // TODO: check perf if `while!` is going to be better or equal
817
811
let! predicateIsTrue = asyncPredicate e.Current
812
+
818
813
if predicateIsTrue then
819
814
yield e.Current
820
815
let! cont = e.MoveNextAsync()
@@ -828,51 +823,42 @@ module internal TaskSeqInternal =
828
823
yield e.Current
829
824
}
830
825
831
- let skipWhile whileKind predicate ( source : TaskSeq < _ >) =
826
+ let skipWhile isInclusive predicate ( source : TaskSeq < _ >) =
832
827
checkNonNull ( nameof source) source
833
828
834
829
taskSeq {
835
830
use e = source.GetAsyncEnumerator CancellationToken.None
831
+ let! notEmpty = e.MoveNextAsync()
832
+ let mutable hasMore = notEmpty
836
833
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
834
+ match predicate with
835
+ | Predicate synchronousPredicate ->
836
+ while hasMore && synchronousPredicate e.Current do
837
+ // keep skipping
838
+ let! cont = e.MoveNextAsync()
839
+ hasMore <- cont
845
840
846
- let mutable cont = true
841
+ | PredicateAsync asyncPredicate ->
842
+ let mutable predicateHolds = true
847
843
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
844
+ while hasMore && predicateHolds do // TODO: check perf if `while!` is going to be better or equal
845
+ let! predicateIsTrue = asyncPredicate e.Current
857
846
858
- while ! e.MoveNextAsync() do // propagate the rest
859
- yield e.Current
847
+ if predicateIsTrue then
848
+ // keep skipping
849
+ let! cont = e.MoveNextAsync()
850
+ hasMore <- cont
860
851
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
852
+ predicateHolds <- predicateIsTrue
871
853
872
- while ! e.MoveNextAsync() do // propagate the rest
873
- yield e.Current
854
+ // "inclusive" means: always skip the item that we pulled, regardless of the result of applying the predicate
855
+ // and only stop thereafter. The non-inclusive versions, in contrast, do not skip the item under which the predicate is false.
856
+ if hasMore && not isInclusive then
857
+ yield e.Current // don't skip, unless inclusive
874
858
875
- cont <- false
859
+ // propagate the rest
860
+ while ! e.MoveNextAsync() do
861
+ yield e.Current
876
862
}
877
863
878
864
// Consider turning using an F# version of this instead?
0 commit comments