I'm working with Lazy Sequences of Ints:
let a = [1,2,3].lazy
I start by defining a Stream of Ints like this:
protocol Stream: LazySequenceProtocol where Element == Int {}
extension LazySequence: Stream where Element == Int {}
extension LazyMapSequence: Stream where Element == Int {}
I will be doing complex things with the streams but to demonstrate the issue I will keep things simple. I extend the stream to allow incrementing values:
extension Stream {
func increment() -> some Stream {
map{ value in
return value + 1
}
}
}
print(Array(a.increment())) // Prints [2, 3, 4]
Note that a.increment() is a lazy function so needs to be surrounded by Array() to turn the results into an array for printing.
Also note the use of the word "some" which was introduced in Swift 5.1 to represent an opaque type and allows us to implement streams in this way - without opaque types this is not so straightforward.
And I can do more interesting things such as inserting 10 times the value after itself:
extension Stream {
func insert10x() -> some Stream {
flatMap{ value in
return [value, value*10]
}
}
}
print(Array(a.insert10x())) // Prints [1, 10, 2, 20, 3, 30]
And this means I can start to compose my functions in different ways:
print(Array(a.insert10x().increment())) // Prints [2, 11, 3, 21, 4, 31]
print(Array(a.increment().insert10x())) // Prints [2, 20, 3, 30, 4, 40]
All the above compiles and works as expected.
BUT... If I introduce an extra line such as the "let multiplier = 10" below then I get compiler errors:
extension Stream {
func insert10xVersion2() -> some Stream {
flatMap{ value in // Error 1
let multiplier = 10
return [value, value * multiplier] // Error 2
}
}
}
print(Array(a.insert10xVersion2())) // Should prints [1, 10, 2, 20, 3, 30]
Two compiler errors:
Error 1: 'flatMap' is deprecated: Please use compactMap(_:) for the case where closure returns an optional value. Use 'compactMap(_:) instead.
Error 2: Cannot convert return expression of type '[Int]' to return type 'Int?'
Both errors seem to indicate that the compiler has decided that flatMap is dealing with optionals so is encouraging use of compactMap instead.
But I would have thought this should produce identical results to the first version!
Perhaps it's a compiler bug but thought I'd check here first to see if anyone can see an issue with my code?