search implements bisection search over t based on the accum values of its prefixes.
Let's consider a t consisting of four elements a; b; c; d (see diagram below) (we'll refer to all of key, data, and accum of a as just a; we'll also assume R.combine = (+)).
Then there are five possible positions to evaluate f at (numbered 0..4 below):
- | position: 0 1 2 3 4 | ------------------------- | element: | a | b | c | d | | ------------------------- | left: 0 a a+b a+b+c a+b+c+d | right: a+b+c+d b+c+d c+d d 0 | f ~left ~right: R R R L L
The function f ~left ~right will be called for a particular position and it takes the sum of the elements to the left and to the right of this position. This means left + right will be equal to accum t.
The return value of f must indicate the direction where the desired element is. In the diagram above f ~left:(a+b) ~right:(c+d) returns `Right, whereas f ~left:(a+b+c) ~right:d returns `Left, which makes c the desired element.
Therefore, search will return c. If f returns the same value at all positions, search returns None.
For it to make sense, f must be monotonic: calling f on every possible position from left to right should produce a prefix of `Right values followed by a suffix of `Left values.
Example:
If the values are positive integers and reduction operation is sum, then you can find the last node where the prefix sum before it is at most x with the following f:
let f ~left ~right:_ = if x < left then `Left else `Right