diff --git a/src/fsharp/FSharp.Core/seq.fs b/src/fsharp/FSharp.Core/seq.fs index 429525ff527..31c7afea626 100644 --- a/src/fsharp/FSharp.Core/seq.fs +++ b/src/fsharp/FSharp.Core/seq.fs @@ -697,6 +697,10 @@ namespace Microsoft.FSharp.Collections and DistinctByFactory<'T,'Key when 'Key: equality> (keyFunction:'T-> 'Key) = inherit SeqComponentFactory<'T,'T> () override __.Create<'V> (_result:Result<'V>) (next:SeqComponent<'T,'V>) : SeqComponent<'T,'V> = upcast DistinctBy (keyFunction, next) + + and ExceptFactory<'T when 'T: equality> (itemsToExclude: seq<'T>) = + inherit SeqComponentFactory<'T,'T> () + override __.Create<'V> (_result:Result<'V>) (next:SeqComponent<'T,'V>) : SeqComponent<'T,'V> = upcast Except (itemsToExclude, next) and FilterFactory<'T> (filter:'T->bool) = inherit SeqComponentFactory<'T,'T> () @@ -791,6 +795,17 @@ namespace Microsoft.FSharp.Collections else false + and Except<'T,'V when 'T: equality> (itemsToExclude: seq<'T>, next:SeqComponent<'T,'V>) = + inherit SeqComponent<'T,'V>(next) + + let cached = lazy(HashSet(itemsToExclude, HashIdentity.Structural)) + + override __.ProcessNext (input:'T) : bool = + if cached.Value.Add input then + Helpers.avoidTailCall (next.ProcessNext input) + else + false + and Filter<'T,'V> (filter:'T->bool, next:SeqComponent<'T,'V>) = inherit SeqComponent<'T,'V>(next) @@ -2311,17 +2326,7 @@ namespace Microsoft.FSharp.Collections [] let except (itemsToExclude: seq<'T>) (source: seq<'T>) = checkNonNull "itemsToExclude" itemsToExclude - checkNonNull "source" source - - seq { - use e = source.GetEnumerator() - if e.MoveNext() then - let cached = HashSet(itemsToExclude, HashIdentity.Structural) - let next = e.Current - if (cached.Add next) then yield next - while e.MoveNext() do - let next = e.Current - if (cached.Add next) then yield next } + source |> seqFactory (SeqComposer.ExceptFactory itemsToExclude) [] let chunkBySize chunkSize (source : seq<_>) =