Factor out tree depth calculation

We'll want to reuse this calculation for trees where the hash is
calculated differently.
Support declarative arrays

These are just maps with positive integers as the keys.  Because arrays
are typically used with adjacent indices and in-order tree traversal
spreads those indices nicely, we don't need a hash function.