LoginSignup
3
3

More than 5 years have passed since last update.

【Swift】使いこなせば便利?〜再帰的列挙型〜

Posted at

これは?

みなさんはSwiftの 再帰的列挙型 というものをご存知でしょうか。

本稿では、意外と知られていない 再帰的列挙型 の使い方について説明します。

再帰的列挙型とは?

再帰的列挙型とは、 associated value としてその列挙型自身を再帰的に持つ列挙型のことです。

言葉だけではわかりにくいので、実際に例を示します。

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

上記のプログラムは、単純な演算を行うための再帰的列挙型の定義です。

一つ目のケースはInt型を associated value として持ちます。
演算のために使う被演算子の定義です。

二つ目と三つ目のケースはそれぞれ加算と乗算の定義です。
そしてどちらも ArithmeticExpression 自身を associated value として持ちます。
このような場合、caseの前に indirect修飾子 を付加します。

活用例

例えば、この ArithmeticExpression を利用して、 (5 + 4) * 2 という演算を処理してみましょう。

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

上記のプログラムは以下のような定義となります。

  • ArithmeticExpressionnumber として five を初期化
  • ArithmeticExpressionnumber として four を初期化
  • ArithmeticExpressionnumber として two を初期化
  • ArithmeticExpressionaddition として fivefour を被演算子に指定して sum を初期化
  • ArithmeticExpressionmultiplication として sumtwo を被演算子に指定して product を初期化

さて、これで演算を行う準備が整いました。
変数 product(5 + 4) * 2 の演算を ArithmeticExpression として持つことになります。

あとはこの ArithmeticExpression を引数に取る評価関数を定義します。

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"

上記の evaluate 関数は以下のような定義となります。

  1. ArithmeticExpressionを引数として受け取る
  2. switch文でケースを分岐する
    • .numberならば: その associated value であるInt型を返す
    • .additionならば: 2つの被演算子をそれぞれ evaluate 関数に引数として渡してその結果を加算する
    • .multiplicationならば: 2つの被演算子をそれぞれ evaluate 関数に引数として渡してその結果を乗算する

この関数 evaluateproduct を引数として渡すと、その演算結果である 18 が返ってきます。

このように、再帰的列挙型は再帰関数とともに扱うことで非常に直感的なコーディングが可能になります。

参考

Apple Inc. “The Swift Programming Language" -Enumerations

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3