2012-02-21 26 views
0

我的作業是實現一個程序,該程序採用函數和二叉樹並從二叉樹輸出滿足函數的整數列表(例如:如果數字是偶數,則函數返回true,因此程序的輸出將是一個偶數列表)。SML中的值異常

我這裏的代碼:

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

有更高的優先級你得到了哪個例外?你的FoundSoFar不是一個有價值的例外嗎? – 2012-02-21 07:47:43

+0

它編譯,它不工作。它實際上說未被發現的異常。 – Arsarcanum 2012-02-21 07:53:03

+0

考慮一下你在做什麼:你正在尋找一個在左右子樹中滿足「p」的元素。如果找到一個,就會拋出一個異常,然後再次執行相同的搜索。所以,自然你會得到同樣的異常再次拋出。 – 2012-02-21 08:17:43

回答

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

您可能想要發現異常,然後對您捕獲的值執行一些有用的操作,但而不是運行的引導異常的表達式完全相同。

P.S.您想要考慮的代碼中另一個與您無關的問題是優先級。 handleif-then-else