Search code examples
lambdaf#functional-programmingcontinuationscontinuation-passing

In F#, how can I turn a list of continuations into a continuation that takes a list?


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)?


Solution

  • 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?