使用特征实例化案例类

时间:2013-08-20 02:38:01

标签: scala case-class traits

如何根据以下特征和案例类实例化树?

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]

来源:Functional Programming in Scala

示例:如何编写String类型的以下树?

           "top"
          /     \
  "middle-left"    "middle-right"
       /          \
  "bottom-left"   "bottom-right"

2 个答案:

答案 0 :(得分:2)

使用您给出的类层次结构,您将无法创建与所需示例树正确相似的内容,因为Branch只能接受左右子树,而不是值(文本“top”) )。

如果您希望分支节点也有值,我会修改您的类层次结构,如下所示:

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

注意子树的Option-al性质,默认为None,允许丢失左或右子树而不使用空值。

然后可以按如下方式生成示例树:

val tree = Branch("top",
                  Some(Branch("middle-left", Some(Leaf("bottom-left")))),
                  Some(Branch("middle-right", right = Some(Leaf("bottom-right")))))

答案 1 :(得分:2)

简短回答

你做不到。您的数据结构的构建方式只能保存叶子中的数据,而不能保存在内部节点中。

答案很长

你这里有一棵monadic树。这个树只能在它的叶子中存储值,但它有一个非常好的属性:当值再次成为monadic树(你在树中有一棵树)时,你可以将构造展平,这样你就可以得到一棵树试。

Haskell中的“Proof”(因为类型类在Scala中有点奇怪)因为是monadic:

data Tree a = Leaf a | Branch (Tree a) (Tree a)

instance Monad Tree where
   return = Leaf
   Leaf a >>= f = f a
   Branch l r >>= f = Branch (l >>= f) (r >>= f)

好吧,这不是一个完整的证明,直到我证明mondic法律适用于这种类型。但我认为你可以看到这个想法。