swiftgenericslazy-evaluationlazy-sequences

Filtering and reducing lazy structures


I would like to filter a lazy structure and then reduce it using Swift language.

func main() -> () {
    let result = (1...)
        .lazy
        .filter { $0 < 3 }
        .reduce(0, {$0 + $1})
    return print(
        result
    )
}

main()

This code compiles; however, the program doesn't execute in a proper way (takes too long). The printed result on the screen should be 3. Is there a way to accomplish this goal ?


Solution

  • The issue is not that your sequence is lazy, it's that your sequence is infinite. You might be looking for the sequence method. Example:

    let s = sequence(first: 0) {
        $0 > 3 ? nil : $0 + 1
    }
    let result = s.reduce(0) { $0 + $1 }
    print(result) // 10
    

    s is lazy and is potentially infinite but not actually infinite, because the method that generates the next item in the series does an early exit by returning nil when the sequence goes past 3. This is similar to your filter except that it is not a filter, it's a stopper. You can use any condition you like here to generate the stopper.