2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Scalaにおけるバリアント型の表現

Last updated at Posted at 2014-10-15

OCamlには、いわゆる代数的データ型の一種として、バリアント型(A型の値かもしれないし、B型の値かもしれないし……、を表現する型)と呼ばれるものがあるそうです。
ocaml.orgに載っている、シンプルな二分木を引用します。

(* Binary tree with leaves car­rying an integer. *)
type tree = Leaf of int | Node of tree * tree

let rec exists_leaf test tree =
  match tree with
  | Leaf v -> test v
  | Node (left, right) ->
      exists_leaf test left
      || exists_leaf test right

let has_even_leaf tree =
  exists_leaf (fun n -> n mod 2 = 0) tree

OCamlを読むのは初めてなのですが、文法知らなくても分かりやすいですね。
これをScalaで書いてみたいと思います。Scala標準にバリアント型そのものはないので、どうしたものかというところなのですが……、Effective Scalaの"Case classes as algebraic data types"に答えが載っていて、継承とcase classを使って表現するのが一般的なようです。
OCamlのコードと比較しやすいように書くと、こんな感じ。

sealed trait Tree[T]
case class Leaf[T](v: T) extends Tree[T]
case class Node[T](left: Tree[T], right: Tree[T]) extends Tree[T]

def exists_leaf[T](test: T => Boolean, tree: Tree[T]): Boolean = {
  tree match {
    case Leaf(v) => test(v)
    case Node(left, right) =>
      exists_leaf(test, left) ||
        exists_leaf(test, right)
  }
}

def has_even_leaf(tree: Tree[Int]): Boolean =
  exists_leaf[Int](_ % 2 == 0, tree)
2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?