Несущие значения исключения в SML - PullRequest
0 голосов
/ 21 февраля 2012

Моя домашняя работа состоит в том, чтобы реализовать программу, которая берет функцию и двоичное дерево и выводит список целых чисел из двоичного дерева, которые выполняют функцию (пример: функция возвращает 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 Ответ

1 голос
/ 21 февраля 2012

Эта часть вашего кода не имеет смысла:

        (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))

Возможно, вы хотели перехватить исключение, а затем сделать что-то полезное с перехваченным значением, но не запустите точно такое же выражение, из-за которого исключение начиналось с.

P.S. Еще одна не связанная проблема в вашем коде, которую вы хотите рассмотреть, это приоритет. handle имеет более высокий приоритет, чем if-then-else

...