Scala 代数的データ型を扱う

個人開発したアプリの宣伝
目的地が設定できる手帳のような使い心地のTODOアプリを公開しています。
Todo with Location

Todo with Location

  • Yoshiko Ichikawa
  • Productivity
  • Free

スポンサードリンク

代数的データ型とは?

複数のデータコンストラクタ(Scalaではclassやobject)を取りまとめた型。オブジェクト指向の抽象クラスのような考えに近いと思った。

ただ、オブジェクト指向の抽象は、使い手が何のインスタンスであるか意識しなくて良いのに対して、代数的データ型は複数の型が入りうるを表現した型なはず。

よって使い手はアクセスしているデータ型は何のコンストラクタに包まれているかを確認する場合がありえる。

enumなんかの列挙型がまさにそれだと思う。

Scalaではtraitを抽象型として利用し定義する。


代数的データ型の定義

Treeという代数的データ型を例として見てみる。

sealed trait Tree[+A]
case class Leaf[A](value: A) extends Tree[A]
case class Branch[A](left:Tree[A], right:Tree[A]) extends Tree[A]

データ型TreeLeafおよびBranchというデータ(値)コンストラクタにより定義される。各データコンストラクタはvalueleft, rightのようなコンストラクタ引数を指定できる。


代数的データ型の値へアクセスする

複数のデータコンストラクタで定義されたデータ型には、パターンマッチでアクセスするのが分かり易い。

以下の例ではLeafデータに引数で与えられたmap関数を適用する。Branchの場合はLeafにあたるまで再帰する。

def map[A, B](t:Tree[A])(f: A => B): Tree[B] = t match {
  case Leaf(value) => Leaf( f(value) )
  case Branch(left, right) => Branch( map(left)(f), map(right)(f) )
}