I've come across this situation numerous times in the past few years where I have some classes like (pseudo-Java):
interface Node<T> { ... }
final class BranchNode<T> implements Node<T> {
List<Node<T>> children;
}
final class LeafNode<T> implements Node<T> {
List<T> elements;
}
If you know the height of a balanced tree in advance, you can make classes for each height of node instead of a single BranchNode class. I think Daniel Spiewak did this in his Scala PersistentVector implementation:
final class Height2Node<T> implements Node<T> {
List<Height1Node<T>> children;
}
final class Height1Node<T> implements Node<T> {
List<LeafNode<T>> children;
}
But if you don't know the height of the tree or need to support an arbitrary height, or only care whether a node is a Branch or a Leaf, is there a type system that can ensure that all your Branches end in Leaves?
I mean, you could walk the tree and use instanceof
to find some leaf nodes and calculate the height of a given node from that and write code to ensure a balanced tree. But I'm wondering if a type system exists that can model this in such a way that it allows building a valid tree and prevents building an invalid one? If so, what is that type system, or class of type systems that can help solve this problem?
I've heard the words, "dependent types" and "higher kinded types" before. I could maybe even recognize simple examples of one or the other, but would have trouble explaining what they mean. So go easy on me, or provide links. Thanks in advance!
NonEmptyList<Node<T>> children
field be enough for you? With the usual caveats (no further subtypes ofNode
, no nulls) it should guarantee that all leaves areLeafNode
. Otherwise, one can always exploit the Church encoding of trees (i.e., modelling a tree using a "visitor pattern"). $\endgroup$BranchNode<T>
requires its children list to be non empty. Doesn't that suffice for your purposes? In that way you can't create aBranchNode<T>
which is a leaf. (You still can break this with nulls, or pointer cycles, but maybe that's enough for you) $\endgroup$