Description of the problem
I have a lazy infinite binary tree:
type 'a tree_node = TN of 'a * 'a inf_btree * 'a inf_btree
and 'a inf_btree = 'a tree_node Lazy.t
let rec ibt_map (f : 'a -> 'b) (t : 'a inf_btree) : 'b inf_btree =
let TN (x, ltree, rtree) = Lazy.force t in
lazy (TN (f x, ibt_map f ltree, ibt_map f rtree))
let rec example : int inf_btree =
lazy (TN (1,
ibt_map ((+) 1) example,
ibt_map ((+) 2) example
)
)
;;
and a lazy stream:
type 'a link_node = LN of 'a * 'a stream
and 'a stream = 'a link_node Lazy.t
Now I want to transform a tree into a stream, in such a way that it preserves the order of the elements in the tree. More precisely, I want elements close to the root to come early in the stream. However, if it's done depth-first then half the tree will never occur in the stream:
let df_tree_to_stream (t : 'a inf_btree) : 'a stream =
let TN (x, ltree, rtree) = Lazy.force t in
let substream1 = df_tree_to_stream ltree in
let substream2 = df_tree_to_stream rtree in
lazy (LN (x, substream1))
(* how to work in substream2 ??? *)
An attempted solution by alternation
We could try to merge the two streams so that they alternate, but then the order of the elements will not be preserved. In the given example, the tree looks like
1
3 2
5 6 4 3
.........
The order of the stream should be
1, 3, 2, 5, 6, 4, 3, ...
But if we simply alternate the streams returned by subtrees, then the tree rooted at 3 would have streams that start with 5 and 6. So this subtree transforms into the stream 3, 5, 6 ...
The other subtree becomes 2, 4, 3 ...
So the overall resulting stream would be
1, 3, 2, 5, 4, ...
We could instead manage the order of visitation of nodes in the tree by maintaining a queue.
Question
My question is, is there simpler a way? Can we get the desired order not using a queue and only using recursion?