First some context: I'm playing around with KFoldTree
from this excellent blog post. I have a tree structure that is n-ary instead of binary. With a binary tree, applying the CPS transform to the function you pass to KFoldTree
is not too hard. You end up with something like:
kleft (fun left -> kright (fun right -> k (dosomethingwith left right)))
The problem with an n-ary tree is that you have to construct this chain of continuations on-the-fly. What you want to end up with should look something like this:
kchildren (fun children -> k (dosomethingwith children))
where children
is a list of the result type of the fold. For example, if I'm writing a pretty-printer, children
should be of type string list
, while kchildren
should be of type (string list -> string) -> string
.
So how do we define a function that produces kchildren
, given a ((Node -> string) -> string) list
(to continue the pretty-printer example)?
This is what I came up with:
let chain continuations cont =
let rec loop acc =
function
| k::ks -> k (fun x -> loop (x::acc) ks)
| [] -> cont acc
// Reverse the input list to preserve original left-to-right order.
List.rev continuations |> loop []
Is there a better way?