← Back to Swift Course | Chapter 10: Enums | Lesson 6 of 6

Recursive Enums

A recursive enum is one that can contain another copy of itself inside it, like a set of nested boxes each holding a smaller box.
Syntax
swift
indirect enum EnumName {
    case leaf(Type)
    case node(EnumName, EnumName)   // holds itself
}

func process(_ e: EnumName) -> Type {
    switch e {
    case .leaf(let v): return v
    case .node(let l, let r): return process(l) /* combine */ process(r)
    }
}

Declaring a Recursive Enum

Marking a case indirect allows it to hold another instance of the same enum, enabling recursive, tree-like structures.

Example: Declaring a Recursive Enum

markup
indirect enum ArithmeticExpression {
    // Case `number`
    case number(Int)
    // Enum case(s): `addition(ArithmeticExpression, ArithmeticExpression)`
    case addition(ArithmeticExpression, ArithmeticExpression)
}
// Declare a constant `expression`, set to `ArithmeticExpression.addition(.number(3), .number(4))`
let expression = ArithmeticExpression.addition(.number(3), .number(4))
// Print `expression` to the console
print(expression)

Evaluating a Recursive Enum

A recursive function that mirrors the enum's structure can walk through nested cases, evaluating them down to a final result.

Example: Evaluating a Recursive Enum

markup
indirect enum ArithmeticExpression {
    // Case `number`
    case number(Int)
    // Enum case(s): `addition(ArithmeticExpression, ArithmeticExpression)`
    case addition(ArithmeticExpression, ArithmeticExpression)
}
// Define the function `evaluate` taking `expression` and returning an Int
func evaluate(_ expression: ArithmeticExpression) -> Int {
    // Switch on `expression` and branch by case
    switch expression {
    // Case: `.number(let value)`
    case .number(let value):
        // Return `value` from this function
        return value
    // Case: `.addition(let left, let right)`
    case .addition(let left, let right):
        // Return `evaluate(left) + evaluate(right)` from this function
        return evaluate(left) + evaluate(right)
    }
}
// Declare a constant `expression`, set to `ArithmeticExpression.addition(.number(3), .addition(.number(4), .number(5)))`
let expression = ArithmeticExpression.addition(.number(3), .addition(.number(4), .number(5)))
// Print `evaluate(expression)` to the console
print(evaluate(expression))
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Forgetting the indirect keyword on a case (or the whole enum) that refers back to itself; without it, Swift can't compute a fixed size for the type.
  2. Confusing indirect case (marks one case as needing indirection) with indirect enum (marks the whole enum), both are valid depending on need.
  3. Writing a recursive function over a recursive enum without a proper base case, causing infinite recursion.
Chapter Summary
  • A case that contains the enum's own type as an associated value must be marked indirect.
  • indirect tells Swift to store that case's data via a pointer instead of inline.
  • Recursive enums are perfect for modeling nested structures like arithmetic expressions or linked lists.
  • Functions processing a recursive enum typically use recursion themselves, matching each case.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.