Recursion 带延拓的尾部递归

Recursion 带延拓的尾部递归,recursion,tail-recursion,ml,Recursion,Tail Recursion,Ml,如何将下面的ML代码转换为尾部递归函数?我盯着它看了几个小时,想弄明白它,但我不知道该怎么做 datatype Tree = NULL | NODE of Tree*Tree | VAL of int; fun dup(NULL) = NULL | dup(VAL(y)) = NODE(VAL(y),VAL(y)) | dup(NODE(y1,y2)) = NODE(dup(y1), dup(y2)); 在这里,转换为连续传递样式(相对而言)很简单——递归是一种棘手的情况 重写右侧有时会更

如何将下面的ML代码转换为尾部递归函数?我盯着它看了几个小时,想弄明白它,但我不知道该怎么做

datatype Tree = NULL | NODE of Tree*Tree | VAL of int;
fun dup(NULL) = NULL
 | dup(VAL(y)) = NODE(VAL(y),VAL(y))
 | dup(NODE(y1,y2)) = NODE(dup(y1), dup(y2));

在这里,转换为连续传递样式(相对而言)很简单——递归是一种棘手的情况

重写右侧有时会更容易看到模式

| dup (NODE (y1, y2)) = let val left = dup y1
                            val right = dup y2
                        in
                            NODE (left, right)
我们需要同时抓取
左侧
右侧
,然后将它们合并。
CPS的不同之处在于,我们传递一个函数来接收这些值,而不是直接接收这些值,然后让提供给我们的continuation来处理结果

将延续命名为“return”,可以如下所示:

fun dup_cont NULL return = return NULL (* Trivial *)
    (* duplicate the value and return it *)
  | dup_cont (VAL y) return = return (NODE (VAL y, VAL y))
    (* recurse, grab the result.
       recurse again, grab result.
       combine the two results and return *)
  | dup_cont (NODE (y1, y2)) return = 
        dup_cont y1 (fn left => dup_cont y2 (fn right => return (NODE (left, right))))

在这里,转换为连续传递样式(相对而言)很简单——递归是一种棘手的情况

重写右侧有时会更容易看到模式

| dup (NODE (y1, y2)) = let val left = dup y1
                            val right = dup y2
                        in
                            NODE (left, right)
我们需要同时抓取
左侧
右侧
,然后将它们合并。
CPS的不同之处在于,我们传递一个函数来接收这些值,而不是直接接收这些值,然后让提供给我们的continuation来处理结果

将延续命名为“return”,可以如下所示:

fun dup_cont NULL return = return NULL (* Trivial *)
    (* duplicate the value and return it *)
  | dup_cont (VAL y) return = return (NODE (VAL y, VAL y))
    (* recurse, grab the result.
       recurse again, grab result.
       combine the two results and return *)
  | dup_cont (NODE (y1, y2)) return = 
        dup_cont y1 (fn left => dup_cont y2 (fn right => return (NODE (left, right))))