Exception SML中的带值异常

Exception SML中的带值异常,exception,tree,sml,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 :

我的家庭作业是实现一个程序,该程序接受一个函数和二叉树,并从二叉树输出一个整数列表来实现该函数(例如:如果数字为偶数,则函数返回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中正确实现带值异常,任何东西都会有帮助,谢谢。

这部分代码没有意义:

        (collect (p, L))@(collect (p, R))
handle FoundSoFar x => x @ (collect (p, L))@(collect (p, R))
如果运行
句柄
部分,则意味着
(collect(p,L))@(collect(p,R))
引发了异常。但是当你处理它的时候你会怎么做呢?再次计算完全相同的表达式(作为句柄表达式右侧的一部分)。因此,很自然,此评估将失败,并再次抛出完全相同的异常,有点像这样:

(collect (p, L))@(collect (p, R)) handle FoundSoFar x => raise FoundSoFar x
因此,最终,您似乎从一开始就没有发现异常:

(collect (p, L))@(collect (p, R))
您可能希望捕获异常,然后对捕获的值执行一些有用的操作,但不要运行导致异常开始的完全相同的表达式


<> P.S.您想考虑的代码中的另一个无关问题是优先级。代码>句柄的优先级高于
if-then-else

您得到了哪个异常?您的FoundsFar不是一个带有值的异常吗?它进行编译,只是不起作用。它实际上说了一个不成立的例外。考虑一下你正在做的事情:你正在寻找一个元素,它满足了左、右子树中的<代码> P<代码>。如果您找到一个异常,将抛出一个异常,您将捕获该异常,然后再次执行相同的搜索。所以,很自然,你会再次抛出相同的异常。然后我不理解你的问题。您得到的异常已经带有一个值。也许您真正的问题是如何获得调试的价值?好的,您可以在定义“r”(抛出的表达式)的表达式周围包装一个“句柄”,并对其进行模式匹配。是的,但是为了调试目的临时更改代码没有什么错。