[swift-evolution] Lazy flatMap for Optionals
Dmitri Gribenko
gribozavr at gmail.com
Sun Dec 6 03:11:19 CST 2015
On Fri, Dec 4, 2015 at 2:38 PM, Donnacha Oisín Kidney <
oisin.kidney at gmail.com> wrote:
> Currently, several of the methods on SequenceType in the standard library
> have lazy variants. flatMap, though, (seems) to have a version missing:
> while there’s a lazy version for nested sequences, there’s no lazy version
> for sequences of Optionals. Is there maybe a reason for this that I
> haven’t thought of? At any rate, here’s what I had in mind:
>
> public struct FlatMapOptionalGenerator<G: GeneratorType, Element>:
> GeneratorType {
> private let f: G.Element -> Element?
> private var g: G
> public mutating func next() -> Element? {
> while let x = g.next() {
> if let y = f(x) {
> return y
> }
> }
> return nil
> }
> }
>
> public struct FlatMapOptionalSequence<S: LazySequenceType, Element>:
> LazySequenceType {
> private let f: S.Generator.Element -> Element?
> private let s: S
> public func generate() -> FlatMapOptionalGenerator<S.Generator, Element>
> {
> return FlatMapOptionalGenerator(f: f, g: s.generate())
> }
> }
>
> extension LazySequenceType {
> public func flatMap<T>(transform: Generator.Element -> T?) ->
> FlatMapOptionalSequence<Self, T> {
> return FlatMapOptionalSequence(f: transform, s: self)
> }
> }
>
>
Hi,
Thank you for the proposal.
Defining only one overload would cause the collection-ness of the input to
be lost. Please take a look at the current flatMap() overloads in
stdlib/public/core/FlatMap.swift: there's one in LazySequenceType, another
one in LazyCollectionType, and one more in LazyCollectionType with
bidirectional indices.
I'm also not a fan of introducing a specialized result type for this
operation: given that we need three overloads, this approach would add six
more types to the library (three sequences and three generators). Current
flatMap() overloads compose existing types, but they rely on intermediate
data structure being a sequence or a collection. Optional is not a
sequence, so that exact approach won't work here. Can you think of another
way we could combine existing types to express the result of this operation?
Dmitri
--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr at gmail.com>*/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151206/8a2a6b1a/attachment.html>
More information about the swift-evolution
mailing list