Created
March 31, 2022 11:23
-
-
Save jjrscott/204ea7844a97b8e92285a3a57b5fe252 to your computer and use it in GitHub Desktop.
Closure based recursive sequence for Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// RecursiveSequence.swift | |
// | |
// Created by John Scott on 31/03/2022. | |
// | |
/// | |
/// To define a sequence by recursion, one needs a rule, called recurrence relation to construct each | |
/// element in terms of the ones before it. In addition, enough initial elements must be provided so | |
/// that all subsequent elements of the sequence can be computed by successive applications of | |
/// the recurrence relation. | |
/// | |
/// For example, to get all daylight saving time transitions for a timezone: | |
/// | |
/// let zone = TimeZone.current | |
/// let transitionDates = GeneratedSequence(initial: .distantPast) { | |
/// zone.nextDaylightSavingTimeTransition(after: $0) | |
/// } | |
/// | |
/// for date in transitionDates { | |
/// print(date) | |
/// } | |
/// | |
/// Or, to get the Fibonacci sequence: | |
/// | |
/// let fibonacci = RecursiveSequence(initial: (1, 1)) { | |
/// ($0 + $1, $0) | |
/// } | |
/// | |
/// for number in fibonacci.lazy.map({ $0.0 }) { | |
/// print(number) | |
/// } | |
struct RecursiveSequence<Element>: Sequence, IteratorProtocol { | |
private var last: Element | |
private let relation: (Element) -> Element? | |
init(initial: Element, relation: @escaping (Element) -> Element?) { | |
last = initial | |
self.relation = relation | |
} | |
mutating func next() -> Element? { | |
let next = relation(last) | |
if let next = next { | |
last = next | |
} | |
return next | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment