【问题标题】:Tail Recursion with continuation带有延续的尾递归
【发布时间】:2017-03-25 03:06:52
【问题描述】:
如何将以下 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));
【问题讨论】:
标签:
recursion
tail-recursion
ml
【解决方案1】:
转换为延续传递风格在这里(相对)简单——递归是一个棘手的情况。
重写右侧有时更容易看到模式。
| dup (NODE (y1, y2)) = let val left = dup y1
val right = dup y2
in
NODE (left, right)
我们需要同时获取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))))