如何将以下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));
答案 0 :(得分:2)
转换为延续传递样式在这里(相对)直截了当 - 递归是一个棘手的案例。
重写右侧有时可以更容易地看到模式。
| dup (NODE (y1, y2)) = let val left = dup y1
val right = dup y2
in
NODE (left, right)
我们需要同时抓住left
和right
并将它们组合起来
CPS的不同之处在于我们传递一个接收这些值而不是直接接收它们的函数,然后我们让给我们的延续处理结果。
命名延续“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))))