如何根据以下特征和案例类实例化树?
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"
答案 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法律适用于这种类型。但我认为你可以看到这个想法。