SML中的价值携带异常

时间:2012-02-21 01:59:03

标签: exception tree sml

我的作业是实现一个带有函数和二叉树的程序,并从二叉树中输出一个完成函数的整数列表(例如:如果数字是偶数,函数返回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中正确实现携带值的异常,任何事情都会有所帮助,谢谢。

1 个答案:

答案 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