Skip to content

Latest commit

 

History

History
52 lines (41 loc) · 2.22 KB

13.5 - Recursive Enumerations.md

File metadata and controls

52 lines (41 loc) · 2.22 KB

A recursive enumeration is an enumeration that has another instance of the enumeration as the associated value for one or more of the enumeration cases. You indicate that an enumeration case is recursive by writing indirect before it, which tells the compiler to insert the necessary layer of indirection.

For example, this is an enumeration that stores arithmetic expressions:

enum ArithmeticExpression {
    case number(Int)
    indirect case addition(ArithmeticExpression, ArithmeticExpression)
    indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}

You can also write indirect before the enum keyword to allow indirection for all the cases that have an associated value:

indirect enum ArithmeticExpression {
    case number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiplication(ArithmeticExpression, ArithmeticExpression)
}

Recursive enumerations are useful because they make it possible to nest enumerations. For instance, we could express (5 + 4) * 2 using the following code:

let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))

A straightforward to handle recursive enumerations is to pair them with a recursive function. For instance, the following function evaluates an arithmetic expression:

func evaluate(_ expression: ArithmeticExpression) -> Int {
    switch expression {
    case let .number(value):
        return value
    case let .addition(left, right):
        return evaluate(left) + evaluate(right)
    case let .multiplication(left, right):
        return evaluate(left) * evaluate(right)
    }
}
 
print(evaluate(product))
// Prints "18"

Previous Note | Back To Contents | Next Section