我想定义一个树状数据结构,其边缘有一个标签,这是我最初的想法:
sealed trait Tree[+N,+E]
case class Branch[N,E](value:N, children:Map[E, Tree[N,E]]) extends Tree[N,E]
case class Leaf[N](value:N) extends Tree[N, Unit]
正如您可能猜到的,如果我创建一个像下面这样的树实例,那么实例的类型将是Tree[Int, Any]
。我也不希望E
具有逆变类型。
val tree =
Branch(0,
Map(
"a" -> Leaf(1),
"b" -> Branch(2,
Map(
"c" -> Leaf(4))))
)
我想知道实施此Tre的更好方法是什么。我听说过修复类型和递归方案,但我不知道它们在这里是否有用。
答案 0 :(得分:0)
Leaf
延长Tree[N, Nothing]
,而非Tree[N, Unit]
。 Nothing
是底部类型,因此Leaf[N]
代表Tree[N, E]
的任何E
的子类型,因为它具有协变性。
case class Leaf[N](value:N) extends Tree[N, Nothing]
通过这种更改,您的示例树定义可以正常工作。
Fixpoint类型更复杂但并非总是必要。但你当然可以修改它以利用它们。如果你确实想要走这条路,最好将它作为另一个更具体的问题。