Skip to content

Commit 53354f3

Browse files
authored
Add conditional LazySequenceProtocol conformance (#29)
* Add conditional LazySequenceProtocol conformance where appropriate * Add laziness tests * Mention conditional conformance to LazySequenceProtocol in the guides
1 parent 8ca636d commit 53354f3

17 files changed

+55
-19
lines changed

Guides/Chain.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ extension Sequence {
2929
public func chained<S: Sequence>(with other: S) -> Concatenation<Self, S>
3030
where Element == S.Element
3131
}
32-
3332
```
3433

35-
The resulting `Chain` type is a sequence, with conditional conformance to the
36-
`Collection`, `BidirectionalCollection`, and `RandomAccessCollection` when both
37-
the first and second arguments conform.
34+
The resulting `Chain` type is a sequence, with conditional conformance to
35+
`Collection`, `BidirectionalCollection`, and `RandomAccessCollection` when both
36+
the first and second arguments conform. `Chain` also conforms to
37+
`LazySequenceProtocol` when the first argument conforms.
3838

3939
### Naming
4040

Guides/Combinations.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ Since the `Combinations` type needs to store an array of the collection’s
5151
indices and mutate the array to generate each permutation, `Combinations` only
5252
has `Sequence` conformance. Adding `Collection` conformance would require
5353
storing the array in the index type, which would in turn lead to copying the
54-
array at every index advancement.
54+
array at every index advancement. `Combinations` does conform to
55+
`LazySequenceProtocol` when the base type conforms.
5556

5657
### Complexity
5758

Guides/Cycle.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@ extension Collection {
3333
```
3434

3535
The new `Cycle` type is a sequence only, given that the `Collection` protocol
36-
design makes infinitely large types impossible/impractical. Note that despite
37-
its name, the returned `FlattenSequence` will always have `Collection`
38-
conformance, and will have `BidirectionalCollection` conformance when called on
39-
a bidirectional collection.
36+
design makes infinitely large types impossible/impractical. `Cycle` also
37+
conforms to `LazySequenceProtocol` when the base type conforms.
38+
39+
Note that despite its name, the returned `FlattenSequence` will always have
40+
`Collection` conformance, and will have `BidirectionalCollection` conformance
41+
when called on a bidirectional collection.
4042

4143
### Complexity
4244

Guides/Indexed.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@ extension Collection {
3030
```
3131

3232
`Indexed` scales from a collection up to a random-access collection, depending on
33-
its base type.
33+
its base type. `Indexed` also conforms to `LazySequenceProtocol` when the base type
34+
conforms.
3435

Guides/Permutations.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ Since the `Permutations` type needs to store an array of the collection’s
7575
indices and mutate the array to generate each permutation, `Permutations` only
7676
has `Sequence` conformance. Adding `Collection` conformance would require
7777
storing the array in the index type, which would in turn lead to copying the
78-
array at every index advancement.
78+
array at every index advancement. `Combinations` does conform to
79+
`LazySequenceProtocol` when the base type conforms.
7980

8081
### Complexity
8182

Sources/Algorithms/Chain.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ extension Chain: BidirectionalCollection
272272

273273
extension Chain: RandomAccessCollection
274274
where Base1: RandomAccessCollection, Base2: RandomAccessCollection {}
275+
extension Chain: LazySequenceProtocol where Base1: LazySequenceProtocol {}
275276

276277
extension Chain: Equatable where Base1: Equatable, Base2: Equatable {}
277278
extension Chain: Hashable where Base1: Hashable, Base2: Hashable {}

Sources/Algorithms/Combinations.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ extension Combinations: Sequence {
122122
}
123123
}
124124

125+
extension Combinations: LazySequenceProtocol where Base: LazySequenceProtocol {}
125126
extension Combinations: Equatable where Base: Equatable {}
126127
extension Combinations: Hashable where Base: Hashable {}
127128

Sources/Algorithms/Cycle.swift

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ extension Cycle: Sequence {
4848
}
4949
}
5050

51+
extension Cycle: LazySequenceProtocol where Base: LazySequenceProtocol {}
52+
5153
//===----------------------------------------------------------------------===//
5254
// cycled()
5355
//===----------------------------------------------------------------------===//
@@ -81,13 +83,7 @@ extension Collection {
8183
public func cycled() -> Cycle<Self> {
8284
Cycle(base: self)
8385
}
84-
}
85-
86-
//===----------------------------------------------------------------------===//
87-
// repeated(count:)
88-
//===----------------------------------------------------------------------===//
89-
90-
extension Collection {
86+
9187
/// Returns a sequence that repeats the elements of this collection the
9288
/// specified number of times.
9389
///

Sources/Algorithms/Indexed.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,14 @@ extension Indexed: BidirectionalCollection where Base: BidirectionalCollection {
6969
}
7070

7171
extension Indexed: RandomAccessCollection where Base: RandomAccessCollection {}
72+
extension Indexed: LazySequenceProtocol where Base: LazySequenceProtocol {}
7273
extension Indexed: Equatable where Base: Equatable {}
7374
extension Indexed: Hashable where Base: Hashable {}
7475

76+
//===----------------------------------------------------------------------===//
77+
// indexed()
78+
//===----------------------------------------------------------------------===//
79+
7580
extension Collection {
7681
/// Returns a collection of pairs *(i, x)*, where *i* represents an index of
7782
/// the collection, and *x* represents an element.

Sources/Algorithms/Permutations.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ extension Permutations: Sequence {
139139
}
140140
}
141141

142+
extension Permutations: LazySequenceProtocol where Base: LazySequenceProtocol {}
143+
142144
//===----------------------------------------------------------------------===//
143145
// nextPermutation(by:)
144146
//===----------------------------------------------------------------------===//
@@ -188,7 +190,7 @@ extension MutableCollection
188190
}
189191

190192
//===----------------------------------------------------------------------===//
191-
// permutations(count:)
193+
// permutations(ofCount:)
192194
//===----------------------------------------------------------------------===//
193195

194196
extension Collection {

Tests/SwiftAlgorithmsTests/ChainTests.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,8 @@ final class ChainTests: XCTestCase {
136136
XCTAssertEqual(chain.distance(from: start, to: end), distance)
137137
}
138138
}
139+
140+
func testChainLazy() {
141+
XCTAssertLazy([1, 2, 3].lazy.chained(with: [4, 5, 6]))
142+
}
139143
}

Tests/SwiftAlgorithmsTests/ChunkedTests.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,9 @@ final class ChunkedTests: XCTestCase {
7171
let lazyChunks = fruits.lazy.chunked(by: { $0.first == $1.first })
7272
validateFruitChunks(lazyChunks)
7373
}
74+
75+
func testChunkedLazy() {
76+
XCTAssertLazy(fruits.lazy.chunked(by: { $0.first == $1.first }))
77+
XCTAssertLazy(fruits.lazy.chunked(on: { $0.first }))
78+
}
7479
}

Tests/SwiftAlgorithmsTests/CombinationsTests.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,8 @@ final class CombinationsTests: XCTestCase {
3838
XCTAssertEqualSequences([], "".combinations(ofCount: 5))
3939
XCTAssertEqualSequences([], "ABCD".combinations(ofCount: 5))
4040
}
41+
42+
func testCombinationsLazy() {
43+
XCTAssertLazy("ABC".lazy.combinations(ofCount: 1))
44+
}
4145
}

Tests/SwiftAlgorithmsTests/CycleTests.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,8 @@ final class CycleTests: XCTestCase {
3939
let empty2 = Array("Hello".cycled(times: 0))
4040
XCTAssert(empty2.isEmpty)
4141
}
42+
43+
func testCycleLazy() {
44+
XCTAssertLazy((1...4).lazy.cycled())
45+
}
4246
}

Tests/SwiftAlgorithmsTests/IndexedTests.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,8 @@ final class IndexedTests: XCTestCase {
2727
let indexOfI = si.last(where: { $0.element == "I" })!.index
2828
XCTAssertEqual("I", s[indexOfI])
2929
}
30+
31+
func testIndexedLazy() {
32+
XCTAssertLazy("ABCD".lazy.indexed())
33+
}
3034
}

Tests/SwiftAlgorithmsTests/PermutationsTests.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,8 @@ final class PermutationsTests: XCTestCase {
6969
while numbers.nextPermutation() {}
7070
XCTAssertEqual([1, 2, 3, 4, 5, 6, 7], numbers)
7171
}
72+
73+
func testPermutationsLazy() {
74+
XCTAssertLazy("ABCD".lazy.permutations(ofCount: 2))
75+
}
7276
}

Tests/SwiftAlgorithmsTests/TestUtilities.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,4 @@ func XCTAssertEqualSequences<S1: Sequence, S2: Sequence>(
6565
try XCTAssert(expression1().elementsEqual(expression2(), by: areEquivalent), message(), file: file, line: line)
6666
}
6767

68+
func XCTAssertLazy<S: LazySequenceProtocol>(_: S) {}

0 commit comments

Comments
 (0)