Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

これは?

みなさんは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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした