code: function VisitorFamily(config) {
    this._shapes = config.shapes;
    this._getTag = config.getTag;
  
    this.Adapter = function(thing, family) {
      this._adaptee = thing;
      this._family = family;
    };
    this.Adapter.prototype.valueOf = function() {
      throw new Error('heeey!');
    };
    this.operations = {};
  
    this._arities = Object.create(null);
    this._getChildren = Object.create(null);
  
    var self = this;
    Object.keys(this._shapes).forEach(function(k) {
      var shape = self._shapes[k];
      self._getChildren[k] = getWalkFn(shape);
  
      // A function means the arity isn't fixed, so don't put an entry in the arity map.
      if (typeof shape !== 'function') {
        self._arities[k] = Array.isArray(shape) ? shape.length : 1;
      }
    });
    this._wrap = function(thing) { return new self.Adapter(thing, self); };
  }
docs: /*
  A VisitorFamily contains a set of recursive operations that are defined over some kind of
  tree structure. The `config` parameter specifies how to walk the tree:
  - 'getTag' is function which, given a node in the tree, returns the node's 'tag' (type)
  - 'shapes' an object that maps from a tag to a value that describes how to recursively
  evaluate the operation for nodes of that type. The value can be:
  a string indicating the property name that holds that node's only child
  an Array of property names (or an empty array indicating a leaf type), or
  a function taking two arguments (node, fn), and returning an Array which is the result
  of apply `fn` to each of the node's children.