Skip to content

Commit 384b464

Browse files
authored
Migrate six operators to the new abstraction. (#814)
* Collect, CombinePrevious, SkipRepeats, UniqueValues * Reduce, ScanMap
1 parent b8de33f commit 384b464

File tree

8 files changed

+262
-157
lines changed

8 files changed

+262
-157
lines changed

ReactiveSwift.xcodeproj/project.pbxproj

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,30 @@
6969
9A1D067D1D948A2300ACF44C /* UnidirectionalBindingSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A1D067C1D948A2200ACF44C /* UnidirectionalBindingSpec.swift */; };
7070
9A1D067E1D948A2300ACF44C /* UnidirectionalBindingSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A1D067C1D948A2200ACF44C /* UnidirectionalBindingSpec.swift */; };
7171
9A1D067F1D948A2300ACF44C /* UnidirectionalBindingSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A1D067C1D948A2200ACF44C /* UnidirectionalBindingSpec.swift */; };
72+
9A2D5CDB259F8398005682ED /* Collect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CDA259F8398005682ED /* Collect.swift */; };
73+
9A2D5CDC259F8398005682ED /* Collect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CDA259F8398005682ED /* Collect.swift */; };
74+
9A2D5CDD259F8398005682ED /* Collect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CDA259F8398005682ED /* Collect.swift */; };
75+
9A2D5CDE259F8398005682ED /* Collect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CDA259F8398005682ED /* Collect.swift */; };
76+
9A2D5CE5259F852B005682ED /* CombinePrevious.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CE4259F852B005682ED /* CombinePrevious.swift */; };
77+
9A2D5CE6259F852B005682ED /* CombinePrevious.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CE4259F852B005682ED /* CombinePrevious.swift */; };
78+
9A2D5CE7259F852B005682ED /* CombinePrevious.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CE4259F852B005682ED /* CombinePrevious.swift */; };
79+
9A2D5CE8259F852B005682ED /* CombinePrevious.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CE4259F852B005682ED /* CombinePrevious.swift */; };
80+
9A2D5CEF259F85AE005682ED /* SkipRepeats.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CEE259F85AE005682ED /* SkipRepeats.swift */; };
81+
9A2D5CF0259F85AE005682ED /* SkipRepeats.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CEE259F85AE005682ED /* SkipRepeats.swift */; };
82+
9A2D5CF1259F85AE005682ED /* SkipRepeats.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CEE259F85AE005682ED /* SkipRepeats.swift */; };
83+
9A2D5CF2259F85AE005682ED /* SkipRepeats.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CEE259F85AE005682ED /* SkipRepeats.swift */; };
84+
9A2D5CF9259F8634005682ED /* UniqueValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CF8259F8634005682ED /* UniqueValues.swift */; };
85+
9A2D5CFA259F8634005682ED /* UniqueValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CF8259F8634005682ED /* UniqueValues.swift */; };
86+
9A2D5CFB259F8634005682ED /* UniqueValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CF8259F8634005682ED /* UniqueValues.swift */; };
87+
9A2D5CFC259F8634005682ED /* UniqueValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5CF8259F8634005682ED /* UniqueValues.swift */; };
88+
9A2D5D03259F8C39005682ED /* Reduce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5D02259F8C39005682ED /* Reduce.swift */; };
89+
9A2D5D04259F8C39005682ED /* Reduce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5D02259F8C39005682ED /* Reduce.swift */; };
90+
9A2D5D05259F8C39005682ED /* Reduce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5D02259F8C39005682ED /* Reduce.swift */; };
91+
9A2D5D06259F8C39005682ED /* Reduce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5D02259F8C39005682ED /* Reduce.swift */; };
92+
9A2D5D0D259F8D1F005682ED /* ScanMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5D0C259F8D1F005682ED /* ScanMap.swift */; };
93+
9A2D5D0E259F8D1F005682ED /* ScanMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5D0C259F8D1F005682ED /* ScanMap.swift */; };
94+
9A2D5D0F259F8D1F005682ED /* ScanMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5D0C259F8D1F005682ED /* ScanMap.swift */; };
95+
9A2D5D10259F8D1F005682ED /* ScanMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5D0C259F8D1F005682ED /* ScanMap.swift */; };
7296
9A2D5C9F259F8059005682ED /* TakeFirst.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5C9E259F8059005682ED /* TakeFirst.swift */; };
7397
9A2D5CA0259F8059005682ED /* TakeFirst.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5C9E259F8059005682ED /* TakeFirst.swift */; };
7498
9A2D5CA1259F8059005682ED /* TakeFirst.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A2D5C9E259F8059005682ED /* TakeFirst.swift */; };
@@ -308,6 +332,12 @@
308332
9A1A4F981E16961C006F3039 /* ValidatingPropertySpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidatingPropertySpec.swift; sourceTree = "<group>"; };
309333
9A1B824020835EEC00EB7C09 /* ResultExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResultExtensions.swift; sourceTree = "<group>"; };
310334
9A1D067C1D948A2200ACF44C /* UnidirectionalBindingSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnidirectionalBindingSpec.swift; sourceTree = "<group>"; };
335+
9A2D5CDA259F8398005682ED /* Collect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Collect.swift; sourceTree = "<group>"; };
336+
9A2D5CE4259F852B005682ED /* CombinePrevious.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombinePrevious.swift; sourceTree = "<group>"; };
337+
9A2D5CEE259F85AE005682ED /* SkipRepeats.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkipRepeats.swift; sourceTree = "<group>"; };
338+
9A2D5CF8259F8634005682ED /* UniqueValues.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UniqueValues.swift; sourceTree = "<group>"; };
339+
9A2D5D02259F8C39005682ED /* Reduce.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reduce.swift; sourceTree = "<group>"; };
340+
9A2D5D0C259F8D1F005682ED /* ScanMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanMap.swift; sourceTree = "<group>"; };
311341
9A2D5C9E259F8059005682ED /* TakeFirst.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TakeFirst.swift; sourceTree = "<group>"; };
312342
9A2D5CAD259F8112005682ED /* TakeLast.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TakeLast.swift; sourceTree = "<group>"; };
313343
9A2D5CB7259F8199005682ED /* TakeWhile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TakeWhile.swift; sourceTree = "<group>"; };
@@ -472,6 +502,12 @@
472502
9AFA491A24E9A925003D263C /* Filter.swift */,
473503
9AFA491F24E9A988003D263C /* CompactMap.swift */,
474504
9AFA492424E9B15C003D263C /* Operators.swift */,
505+
9A2D5CDA259F8398005682ED /* Collect.swift */,
506+
9A2D5CE4259F852B005682ED /* CombinePrevious.swift */,
507+
9A2D5CEE259F85AE005682ED /* SkipRepeats.swift */,
508+
9A2D5CF8259F8634005682ED /* UniqueValues.swift */,
509+
9A2D5D02259F8C39005682ED /* Reduce.swift */,
510+
9A2D5D0C259F8D1F005682ED /* ScanMap.swift */,
475511
9A2D5C9E259F8059005682ED /* TakeFirst.swift */,
476512
9A2D5CAD259F8112005682ED /* TakeLast.swift */,
477513
9A2D5CB7259F8199005682ED /* TakeWhile.swift */,
@@ -978,18 +1014,25 @@
9781014
57A4D1B61BA13D7A00F7D4B1 /* Event.swift in Sources */,
9791015
57A4D1B81BA13D7A00F7D4B1 /* Scheduler.swift in Sources */,
9801016
9A9100E21E0E6E680093E346 /* ValidatingProperty.swift in Sources */,
1017+
9A2D5CF2259F85AE005682ED /* SkipRepeats.swift in Sources */,
9811018
9A2D5CBB259F8199005682ED /* TakeWhile.swift in Sources */,
9821019
57A4D1B91BA13D7A00F7D4B1 /* Action.swift in Sources */,
9831020
57A4D1BA1BA13D7A00F7D4B1 /* Property.swift in Sources */,
9841021
9A2D5C5C259F7B31005682ED /* Materialize.swift in Sources */,
9851022
9A090C171DA0309E00EE97CA /* Reactive.swift in Sources */,
9861023
57A4D1BB1BA13D7A00F7D4B1 /* Signal.swift in Sources */,
9871024
9AFA492824E9B15C003D263C /* Operators.swift in Sources */,
1025+
9A2D5D10259F8D1F005682ED /* ScanMap.swift in Sources */,
1026+
9A2D5CE8259F852B005682ED /* CombinePrevious.swift in Sources */,
9881027
9A67963E1F6059440058C5B4 /* UninhabitedTypeGuards.swift in Sources */,
1028+
9A2D5D06259F8C39005682ED /* Reduce.swift in Sources */,
1029+
9AFA491424E9A196003D263C /* Map.swift in Sources */,
1030+
9A2D5CFC259F8634005682ED /* UniqueValues.swift in Sources */,
9891031
9A2D5C66259F7B47005682ED /* MaterializeAsResult.swift in Sources */,
9901032
9AFA491424E9A196003D263C /* Map.swift in Sources */,
9911033
9A2D5C8E259F7ED5005682ED /* Dematerialize.swift in Sources */,
9921034
9AFA491E24E9A925003D263C /* Filter.swift in Sources */,
1035+
9A2D5CDE259F8398005682ED /* Collect.swift in Sources */,
9931036
57A4D1BC1BA13D7A00F7D4B1 /* SignalProducer.swift in Sources */,
9941037
57A4D1BD1BA13D7A00F7D4B1 /* Atomic.swift in Sources */,
9951038
57A4D1BE1BA13D7A00F7D4B1 /* Bag.swift in Sources */,
@@ -1050,18 +1093,25 @@
10501093
A9B315BE1B3940810001CB9C /* Event.swift in Sources */,
10511094
A9B315C01B3940810001CB9C /* Scheduler.swift in Sources */,
10521095
9A9100E11E0E6E680093E346 /* ValidatingProperty.swift in Sources */,
1096+
9A2D5CF1259F85AE005682ED /* SkipRepeats.swift in Sources */,
10531097
9A2D5CBA259F8199005682ED /* TakeWhile.swift in Sources */,
10541098
A9B315C11B3940810001CB9C /* Action.swift in Sources */,
10551099
A9B315C21B3940810001CB9C /* Property.swift in Sources */,
10561100
9A2D5C5B259F7B31005682ED /* Materialize.swift in Sources */,
10571101
9A090C161DA0309E00EE97CA /* Reactive.swift in Sources */,
10581102
A9B315C31B3940810001CB9C /* Signal.swift in Sources */,
10591103
9AFA492724E9B15C003D263C /* Operators.swift in Sources */,
1104+
9A2D5D0F259F8D1F005682ED /* ScanMap.swift in Sources */,
1105+
9A2D5CE7259F852B005682ED /* CombinePrevious.swift in Sources */,
10601106
9A67963D1F6059430058C5B4 /* UninhabitedTypeGuards.swift in Sources */,
1107+
9A2D5D05259F8C39005682ED /* Reduce.swift in Sources */,
1108+
9AFA491324E9A196003D263C /* Map.swift in Sources */,
1109+
9A2D5CFB259F8634005682ED /* UniqueValues.swift in Sources */,
10611110
9A2D5C65259F7B47005682ED /* MaterializeAsResult.swift in Sources */,
10621111
9AFA491324E9A196003D263C /* Map.swift in Sources */,
10631112
9A2D5C8D259F7ED5005682ED /* Dematerialize.swift in Sources */,
10641113
9AFA491D24E9A925003D263C /* Filter.swift in Sources */,
1114+
9A2D5CDD259F8398005682ED /* Collect.swift in Sources */,
10651115
A9B315C41B3940810001CB9C /* SignalProducer.swift in Sources */,
10661116
A9B315C51B3940810001CB9C /* Atomic.swift in Sources */,
10671117
A9B315C61B3940810001CB9C /* Bag.swift in Sources */,
@@ -1094,18 +1144,25 @@
10941144
D0C312D319EF2A5800984962 /* Disposable.swift in Sources */,
10951145
9A9100DF1E0E6E620093E346 /* ValidatingProperty.swift in Sources */,
10961146
EBCC7DBC1BBF010C00A2AE92 /* Signal.Observer.swift in Sources */,
1147+
9A2D5CEF259F85AE005682ED /* SkipRepeats.swift in Sources */,
10971148
9A2D5CB8259F8199005682ED /* TakeWhile.swift in Sources */,
10981149
D03B4A3D19F4C39A009E02AC /* FoundationExtensions.swift in Sources */,
10991150
9A090C141DA0309E00EE97CA /* Reactive.swift in Sources */,
11001151
9A2D5C59259F7B31005682ED /* Materialize.swift in Sources */,
11011152
D08C54B31A69A2AE00AD8286 /* Signal.swift in Sources */,
11021153
D85C652A1C0D84C7005A77AD /* Flatten.swift in Sources */,
11031154
9AFA492524E9B15C003D263C /* Operators.swift in Sources */,
1155+
9A2D5D0D259F8D1F005682ED /* ScanMap.swift in Sources */,
1156+
9A2D5CE5259F852B005682ED /* CombinePrevious.swift in Sources */,
11041157
9A67963B1F6056B90058C5B4 /* UninhabitedTypeGuards.swift in Sources */,
1158+
9A2D5D03259F8C39005682ED /* Reduce.swift in Sources */,
1159+
9AFA491124E9A196003D263C /* Map.swift in Sources */,
1160+
9A2D5CF9259F8634005682ED /* UniqueValues.swift in Sources */,
11051161
9A2D5C63259F7B47005682ED /* MaterializeAsResult.swift in Sources */,
11061162
9AFA491124E9A196003D263C /* Map.swift in Sources */,
11071163
9A2D5C8B259F7ED5005682ED /* Dematerialize.swift in Sources */,
11081164
9AFA491B24E9A925003D263C /* Filter.swift in Sources */,
1165+
9A2D5CDB259F8398005682ED /* Collect.swift in Sources */,
11091166
D0C312CF19EF2A5800984962 /* Bag.swift in Sources */,
11101167
4A0E10FF1D2A92720065D310 /* Lifetime.swift in Sources */,
11111168
D0C312E719EF2A5800984962 /* Scheduler.swift in Sources */,
@@ -1166,18 +1223,25 @@
11661223
D0C312D419EF2A5800984962 /* Disposable.swift in Sources */,
11671224
D08C54B91A69A9D100AD8286 /* SignalProducer.swift in Sources */,
11681225
9A9100E01E0E6E670093E346 /* ValidatingProperty.swift in Sources */,
1226+
9A2D5CF0259F85AE005682ED /* SkipRepeats.swift in Sources */,
11691227
9A2D5CB9259F8199005682ED /* TakeWhile.swift in Sources */,
11701228
9ABCB1861D2A5B5A00BCA243 /* Deprecations+Removals.swift in Sources */,
11711229
EBCC7DBD1BBF01E100A2AE92 /* Signal.Observer.swift in Sources */,
11721230
9A2D5C5A259F7B31005682ED /* Materialize.swift in Sources */,
11731231
9A090C151DA0309E00EE97CA /* Reactive.swift in Sources */,
11741232
D85C652B1C0E70E3005A77AD /* Flatten.swift in Sources */,
11751233
9AFA492624E9B15C003D263C /* Operators.swift in Sources */,
1234+
9A2D5D0E259F8D1F005682ED /* ScanMap.swift in Sources */,
1235+
9A2D5CE6259F852B005682ED /* CombinePrevious.swift in Sources */,
11761236
9A67963C1F6059420058C5B4 /* UninhabitedTypeGuards.swift in Sources */,
1237+
9A2D5D04259F8C39005682ED /* Reduce.swift in Sources */,
1238+
9AFA491224E9A196003D263C /* Map.swift in Sources */,
1239+
9A2D5CFA259F8634005682ED /* UniqueValues.swift in Sources */,
11771240
9A2D5C64259F7B47005682ED /* MaterializeAsResult.swift in Sources */,
11781241
9AFA491224E9A196003D263C /* Map.swift in Sources */,
11791242
9A2D5C8C259F7ED5005682ED /* Dematerialize.swift in Sources */,
11801243
9AFA491C24E9A925003D263C /* Filter.swift in Sources */,
1244+
9A2D5CDC259F8398005682ED /* Collect.swift in Sources */,
11811245
4A0E11001D2A92720065D310 /* Lifetime.swift in Sources */,
11821246
D08C54BB1A69C54400AD8286 /* Property.swift in Sources */,
11831247
D03B4A3E19F4C39A009E02AC /* FoundationExtensions.swift in Sources */,

Sources/Event.swift

Lines changed: 14 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -325,38 +325,6 @@ extension Signal.Event where Value: OptionalProtocol {
325325
}
326326
}
327327

328-
/// A reference type which wraps an array to auxiliate the collection of values
329-
/// for `collect` operator.
330-
private final class CollectState<Value> {
331-
var values: [Value] = []
332-
333-
/// Collects a new value.
334-
func append(_ value: Value) {
335-
values.append(value)
336-
}
337-
338-
/// Check if there are any items remaining.
339-
///
340-
/// - note: This method also checks if there weren't collected any values
341-
/// and, in that case, it means an empty array should be sent as the
342-
/// result of collect.
343-
var isEmpty: Bool {
344-
/// We use capacity being zero to determine if we haven't collected any
345-
/// value since we're keeping the capacity of the array to avoid
346-
/// unnecessary and expensive allocations). This also guarantees
347-
/// retro-compatibility around the original `collect()` operator.
348-
return values.isEmpty && values.capacity > 0
349-
}
350-
351-
/// Removes all values previously collected if any.
352-
func flush() {
353-
// Minor optimization to avoid consecutive allocations. Can
354-
// be useful for sequences of regular or similar size and to
355-
// track if any value was ever collected.
356-
values.removeAll(keepingCapacity: true)
357-
}
358-
}
359-
360328
extension Signal.Event {
361329
internal static var collect: Transformation<[Value], Error> {
362330
return collect { _, _ in false }
@@ -368,54 +336,14 @@ extension Signal.Event {
368336
}
369337

370338
internal static func collect(_ shouldEmit: @escaping (_ collectedValues: [Value]) -> Bool) -> Transformation<[Value], Error> {
371-
return { action, _ in
372-
let state = CollectState<Value>()
373-
374-
return Signal.Observer { event in
375-
switch event {
376-
case let .value(value):
377-
state.append(value)
378-
if shouldEmit(state.values) {
379-
action(.value(state.values))
380-
state.flush()
381-
}
382-
case .completed:
383-
if !state.isEmpty {
384-
action(.value(state.values))
385-
}
386-
action(.completed)
387-
case let .failed(error):
388-
action(.failed(error))
389-
case .interrupted:
390-
action(.interrupted)
391-
}
392-
}
339+
return { downstream, _ in
340+
Operators.Collect(downstream: downstream, shouldEmit: shouldEmit)
393341
}
394342
}
395343

396344
internal static func collect(_ shouldEmit: @escaping (_ collected: [Value], _ latest: Value) -> Bool) -> Transformation<[Value], Error> {
397-
return { action, _ in
398-
let state = CollectState<Value>()
399-
400-
return Signal.Observer { event in
401-
switch event {
402-
case let .value(value):
403-
if shouldEmit(state.values, value) {
404-
action(.value(state.values))
405-
state.flush()
406-
}
407-
state.append(value)
408-
case .completed:
409-
if !state.isEmpty {
410-
action(.value(state.values))
411-
}
412-
action(.completed)
413-
case let .failed(error):
414-
action(.failed(error))
415-
case .interrupted:
416-
action(.interrupted)
417-
}
418-
}
345+
return { downstream, _ in
346+
Operators.Collect(downstream: downstream, shouldEmit: shouldEmit)
419347
}
420348
}
421349

@@ -424,83 +352,26 @@ extension Signal.Event {
424352
/// `nil` literal would be materialized as `Optional<Value>.none` instead of `Value`,
425353
/// thus changing the semantic.
426354
internal static func combinePrevious(initial: Value?) -> Transformation<(Value, Value), Error> {
427-
return { action, _ in
428-
var previous = initial
429-
430-
return Signal.Observer { event in
431-
switch event {
432-
case let .value(value):
433-
if let previous = previous {
434-
action(.value((previous, value)))
435-
}
436-
previous = value
437-
case .completed:
438-
action(.completed)
439-
case let .failed(error):
440-
action(.failed(error))
441-
case .interrupted:
442-
action(.interrupted)
443-
}
444-
}
355+
return { downstream, _ in
356+
Operators.CombinePrevious(downstream: downstream, initial: initial)
445357
}
446358
}
447359

448360
internal static func skipRepeats(_ isEquivalent: @escaping (Value, Value) -> Bool) -> Transformation<Value, Error> {
449-
return { action, _ in
450-
var previous: Value?
451-
452-
return Signal.Observer { event in
453-
switch event {
454-
case let .value(value):
455-
if let previous = previous, isEquivalent(previous, value) {
456-
return
457-
}
458-
previous = value
459-
fallthrough
460-
case .completed, .interrupted, .failed:
461-
action(event)
462-
}
463-
}
361+
return { downstream, _ in
362+
Operators.SkipRepeats(downstream: downstream, isEquivalent: isEquivalent)
464363
}
465364
}
466365

467366
internal static func uniqueValues<Identity: Hashable>(_ transform: @escaping (Value) -> Identity) -> Transformation<Value, Error> {
468-
return { action, _ in
469-
var seenValues: Set<Identity> = []
470-
471-
return Signal.Observer { event in
472-
switch event {
473-
case let .value(value):
474-
let identity = transform(value)
475-
let (inserted, _) = seenValues.insert(identity)
476-
if inserted {
477-
fallthrough
478-
}
479-
480-
case .failed, .completed, .interrupted:
481-
action(event)
482-
}
483-
}
367+
return { downstream, _ in
368+
Operators.UniqueValues(downstream: downstream, extract: transform)
484369
}
485370
}
486371

487372
internal static func reduce<U>(into initialResult: U, _ nextPartialResult: @escaping (inout U, Value) -> Void) -> Transformation<U, Error> {
488-
return { action, _ in
489-
var accumulator = initialResult
490-
491-
return Signal.Observer { event in
492-
switch event {
493-
case let .value(value):
494-
nextPartialResult(&accumulator, value)
495-
case .completed:
496-
action(.value(accumulator))
497-
action(.completed)
498-
case .interrupted:
499-
action(.interrupted)
500-
case let .failed(error):
501-
action(.failed(error))
502-
}
503-
}
373+
return { downstream, _ in
374+
Operators.Reduce(downstream: downstream, initial: initialResult, nextPartialResult: nextPartialResult)
504375
}
505376
}
506377

@@ -520,22 +391,8 @@ extension Signal.Event {
520391
}
521392

522393
internal static func scanMap<State, U>(into initialState: State, _ next: @escaping (inout State, Value) -> U) -> Transformation<U, Error> {
523-
return { action, _ in
524-
var accumulator = initialState
525-
526-
return Signal.Observer { event in
527-
switch event {
528-
case let .value(value):
529-
let output = next(&accumulator, value)
530-
action(.value(output))
531-
case .completed:
532-
action(.completed)
533-
case .interrupted:
534-
action(.interrupted)
535-
case let .failed(error):
536-
action(.failed(error))
537-
}
538-
}
394+
return { downstream, _ in
395+
Operators.ScanMap(downstream: downstream, initial: initialState, next: next)
539396
}
540397
}
541398

0 commit comments

Comments
 (0)