Recursive constraints & higher-order generics
Write recursive constraints (e.g., nested sequences) and higher-order generic functions that take generic closures/functions.
Recursive constraints & higher-order generics is a free Swift Academy lesson on CoddyKit — lesson 2 of 3. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Swift Academy learning path, one of 3 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What & why
This lesson shows:
- Recursive constraints: constraints on nested generic members (e.g., Sequence of Sequence).
- Higher-order generics: generic functions that accept generic closures/functions.
Nested sequences (flatten)
A classic recursive constraint: we require C.Element: Sequence so we can iterate two levels deep.
// Works for any Collection whose elements are Sequences
func flatten<C: Collection>(_ c: C) -> [C.Element.Element]
where C.Element: Sequence {
var result: [C.Element.Element] = []
result.reserveCapacity(c.reduce(0) { $0 + ($1 as AnySequence<C.Element.Element>).underestimatedCount })
for inner in c {
for e in inner { result.append(e) }
}
return result
}
let nested = [[1,2], [3], [4,5]]
print(flatten(nested)) // [1,2,3,4,5]Map nested generically
We constrain twice: C: Collection and C.Element: Collection, letting us call map at each level.
// Map over a two-level structure without fixing concrete types
func mapNested<C: Collection, R>(_ c: C, _ transform: (C.Element.Element) -> R) -> [[R]]
where C.Element: Collection {
return c.map { inner in inner.map(transform) }
}
let doubled = mapNested([[1,2],[3]], { $0 * 2 })
print(doubled) // [[2,4],[6]]compose(f,g)
Higher-order generics: the function is generic over functions themselves, building reusable pipelines like compose.
// Compose two generic transforms that work on the same element type
func compose<A, B, C>(
_ f: @escaping (B) -> C,
_ g: @escaping (A) -> B
) -> (A) -> C {
{ a in f(g(a)) }
}
let toString: (Int) -> String = { "\\($0)" }
let length: (String) -> Int = { $0.count }
let intToLen = compose(length, toString)
print(intToLen(1234)) // 4Generic closure params
The closure f is a generic parameter too. We keep types flexible via where constraints.
// A generic "transform each" that accepts ANY transform (generic in T/U)
func transformEach<T, U, C: Collection>(_ c: C, using f: (T) -> U) -> [U]
where C.Element == T {
var out: [U] = []
out.reserveCapacity(c.count)
for x in c { out.append(f(x)) }
return out
}
let words = ["swift","kit"]
print(transformEach(words, using: { $0.uppercased() })) // ["SWIFT","KIT"]Guidelines
Tips:
- Write the smallest constraints you need (
SequencevsCollection). - Prefer where clauses for readability.
- Test with multiple concrete types to ensure generality.
- Document assumptions (e.g., element order, uniqueness).
Higher-order generics definition
Quick check: What makes a function a higher-order generic one?
Recap
Recap: Use recursive constraints (e.g., C.Element: Sequence) to work with nested generics; use higher-order generics to compose reusable function pipelines cleanly.
Frequently asked questions
Is the “Recursive constraints & higher-order generics” lesson free?
Yes — the full text of “Recursive constraints & higher-order generics” is free to read here on the web, and the Swift Academy course includes 3 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Swift Academy course, upgrade to CoddyKit PRO.
What will I learn in “Recursive constraints & higher-order generics”?
Write recursive constraints (e.g., nested sequences) and higher-order generic functions that take generic closures/functions. You practise Swift Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Swift Academy?
No prior experience is required. Swift Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 3, so you can start here or from the beginning and move at your own pace.
How long does the “Recursive constraints & higher-order generics” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Swift Academy lesson?
Yes. Every Swift Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Conditional conformances
- Recursive constraints & higher-order generics
- where clauses on extensions