Skip to content

Instantly share code, notes, and snippets.

@jjrscott
Created March 31, 2022 11:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jjrscott/204ea7844a97b8e92285a3a57b5fe252 to your computer and use it in GitHub Desktop.
Save jjrscott/204ea7844a97b8e92285a3a57b5fe252 to your computer and use it in GitHub Desktop.
Closure based recursive sequence for Swift
//
// 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