代数数据类型(ADT),ADT是由一个或者多个数据构造器所定义的数据类型,一个构造器可以包含一个或者多个参数。数据类型(data type)是其数据构造器(data construct)的累加(sum)和联合(union),每个数据构造器又是它参数的乘积,所以我们又称为代数数据类型(algebraic data type)。
代数数据类型被用于定义其它数据结构,让我们定义一个简单的二叉树数据结构:
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]
练习 3.25
写一个size函数。统计一棵树的中的节点数(叶子节点和分支节点)
def size[A](t: Tree[A]): Int = t match {
case Leaf(_) => 1
case Branch(l, r) => 1 + size(l) + size(r)
}
练习 3.26
写一个maximum函数,返回Tree[Int]中的最大的元素。
def maximum(t: Tree[Int]): Int = t match {
case Leaf(a) => a
case Branch(l, r) => maximum(l).max(maximum(r))
}
练习 3.27
写一个depth函数,返回一棵树中从根节点到任何叶子结点的最大路径长度。
def depth[A](t: Tree[A]): Int = t match {
case Leaf(_) => 0
case Branch(l, r) => 1 + depth(l) + depth(r)
}
练习 3.28
写一个map函数,类似List中的同名函数,接受一个函数,对树中的每个元素进行修改
def map[A, B](t: Tree[A])(f: A => B): Tree[B] = t match {
case Leaf(a) => Leaf(f(a))
case Branch(l, r) => Branch(map(l)(f), map(r)(f))
}
练习 3.29
泛化size、maximum、depth和map函数,写一个新的函数fold,对它们的相似性抽象。
def fold[A, B](t: Tree[A])(f: A => B)(g: (B, B) => B): B = t match {
case Leaf(a) => f(a)
case Branch(l, r) => g(fold(l)(f)(g), fold(r)(f)(g))
}
def size1[A](t: Tree[A]): Int =
fold(t)(a => 1)(1 + _ + _)
def maximum1(t: Tree[Int]): Int =
fold(t)(a => a)(_.max(_))
def depth1[A](t: Tree[A]): Int =
fold(t)(a => 0)(1 + _ + _)
def map1[A, B](t: Tree[A])(f: A => B): Tree[B] =
fold(t)(a => Leaf(f(a)).asInstanceOf[Tree[B]])(Branch(_, _))