我的作业是实现一个带有函数和二叉树的程序,并从二叉树中输出一个完成函数的整数列表(例如:如果数字是偶数,函数返回true,因此程序的输出将是偶数整数列表。
我的代码在这里:
datatype 'a tree = Empty | Node of ('a tree * int * 'a tree)
fun collect (p, Empty) = []
|collect (p, Node (L, x, R)) =
if (p x) then x :: (collect (p, L) @ collect (p, R))
else
collect (p, L) @ collect (p, R);
哪个工作正常,但是赋值需要我用异常实现这个函数。我们应该使用携带价值的功能,但我的代码不起作用:
fun collect (p, Empty) = []
| collect (p, (Node(L, x, R))) =
if (p x) then (raise FoundSoFar [x])
else
(collect (p, L))@(collect (p, R))
handle FoundSoFar x => x @ (collect (p, L))@(collect (p, R))
编译正确,但是当我尝试老师给出的测试代码时:
val L = Node (Node (Empty, 2, Empty), 5, Node (Empty, 6, Empty));
val R = Node (Empty, 12, Empty);
val T = Node (Node (L, 7, Node (Empty, 8, Empty)), 11, R);
val r = collect ((fn x => (x mod 2) = 0) , T);
我刚收到未捕获的异常错误... 我要么需要帮助,了解我的代码是错误的,如何解决它,以及\或如何在SML中正确实现携带值的异常,任何事情都会有所帮助,谢谢。
答案 0 :(得分:1)
这部分代码没有意义:
(collect (p, L))@(collect (p, R))
handle FoundSoFar x => x @ (collect (p, L))@(collect (p, R))
如果运行handle
部分,则表示(collect (p, L))@(collect (p, R))
引发了异常。但是当你处理它时你会怎么做?您再次评估完全相同的表达式 (作为句柄表达式右侧的一部分)。很自然地,这个评估会失败并再次抛出完全相同的异常,有点像这样:
(collect (p, L))@(collect (p, R)) handle FoundSoFar x => raise FoundSoFar x
所以最后,就好像你从来没有抓住过这个例外:
(collect (p, L))@(collect (p, R))
您可能想要捕获异常,然后使用您捕获的值执行一些有用的操作,但 not 运行导致异常开始的完全相同的表达式。
P.S。您要考虑的代码中另一个不相关的问题是优先级。 handle
的优先级高于if-then-else