Binary trees

There is a standard type of rose trees (Tree) defined in the
containers package, but there is no standard type for binary
trees, so we define one here. Note, if you want to draw binary
trees with data of type a at the leaves, you can use something
like BTree (Maybe a) with Nothing at internal nodes;
renderTree lets you specify how to draw each node.

Lay out a binary tree using a slight variant of the symmetric
layout algorithm, using default options. In particular, if a
node has only a left child but no right child (or vice versa),
the child will be offset from the parent horizontally by half the
horizontal separation parameter. Note that the result will be
Nothing if and only if the input tree is Empty.

Lay out a binary tree using a slight variant of the symmetric
layout algorithm. In particular, if a node has only a left child
but no right child (or vice versa), the child will be offset from
the parent horizontally by half the horizontal separation
parameter. Note that the result will be Nothing if and only if
the input tree is Empty.

A function for measuring the horizontal extent (a pair
of x-coordinates) of an item in the tree. The default
is const (0,0), that is, the nodes are considered as
taking up no space, so the centers of the nodes will
be separated according to the slHSep and slVSep.
However, this can be useful, e.g. if you have a tree
of diagrams of irregular size and want to make sure no
diagrams overlap. In that case you could use
fromMaybe (0,0) . extentX.

Draw a tree annotated with node positions, given functions
specifying how to draw nodes and edges. Unlike renderTree,
this version gives the edge-drawing function access to the actual
values stored at the nodes rather than just their positions.