CTMacUser
(Daryle Walker)
1
Would variants of the Sequence mapping methods that don't return Array, but a user-specified RangeReplaceableCollection type be useful?
extension Sequence {
func compactMap<ElementOfResult, ContainerOfResult: RangeReplaceableCollection>(as: ContainerOfResult.Type, _ transform: (Element) throws -> ElementOfResult?) rethrows -> ContainerOfResult where ContainerOfResult.Element == ElementOfResult {
var result = ContainerOfResult(), iterator = makeIterator()
while let e = iterator.next() {
if let er = try transform(e) {
result.append(er)
}
}
return result
}
func flatMap<SegmentOfResult: Sequence, ContainerOfResult: RangeReplaceableCollection>(as: ContainerOfResult.Type, _ transform: (Element) throws -> SegmentOfResult) rethrows -> ContainerOfResult where ContainerOfResult.Element == SegmentOfResult.Element {
var result = ContainerOfResult(), iterator = makeIterator()
while let e = iterator.next() {
result.append(contentsOf: try transform(e))
}
return result
}
}
I skipped some of the others because I couldn't figure out how to implement them better than calling the Array-returning version then converting.
Ben_Cohen
(Ben Cohen)
2
I would say generally no. These are all trivially compassable with a combination of RRC's init + lazy equivalents:
let seq = 0..<10
let ca = ContiguousArray(seq.lazy.map(String.init))
1 Like
What @Ben_Cohen said, however I'm keen to see iff we get higher kinded types and some other generic features if those functions might switch to a different representation.
The following syntax is not valid Swift syntax, it's completely hypothetical and borrows a few forms that were floating around here on the forums:
protocol Sequence {
associatedtype Element
func map<Result>(
_ closure: (Self.Element) throws -> Result.Element /* = { $0 } */
) rethrows -> Result where Result ~= Self
func compactMap<Result>(
_ closure: (Self.Element) throws -> Result.Element?
) rethrows -> Result where Result ~= Self
func flatMap<T, Result>(
_ closure: (Self.Element) throws -> T
) rethrows -> Result
where
T : Sequence,
Result ~= Self,
Result.Element == T.Element
}
Result ~= Self differs from Result == Self that is only a Sequence with un-specified constraints such as Element, which allows us to re-assign it in through type inference of the function. The above example also has a commented out part that indicates that for instance map should by default map to Self if no explicit type provided, otherwise it could theoretically map to any other sequence type.
1 Like