2013-11-24 36 views
0

我正在嘗試製作一個打印二叉樹的函數。我二叉樹的數據類型如下:使用ML中的單位(SML/NJ)

datatype 'a BT = empty | bTree of 'a * 'a BT * 'a BT; 

我也提出,打印整數,我將使用該節點的功能:

fun printInt n = print (Int.toString n); 

正如你可以看到,BT數據類型有3個節點('a',BT,'BT),我已經開始製作displayTree函數,但是找不到打印出printInt函數返回的單元類型的方法。我相信還有其他方法可以做到這一點,但在這種情況下,我將如何返回三個連接的單元類型。這是我到目前爲止(我知道@是不正確的)。

fun displayTree T = 
let 
    val bTree (root, left, right) = T; 
in 
    (printInt root)@ (displayTree left) @ (displayTree right) 
end; 

我不擔心樹的行格式化。我只是不確定如何追加我的(printInt根)到遞歸調用。

編輯:

我想displayTree功能是多態

回答

1

你必須要爲了得到這個代碼工作幾點變化:

更改樹定義:

datatype btree = 
       Empty | 
       Node of int * btree * btree; 

printInt功能很簡短,所以我會在這種情況下避免它:

fun displayTree T = 
    case T of 
     Empty    => "" 
     |Node(root, left, right) => (Int.toString root)^(displayTree left)^(displayTree right) 

請注意,此函數返回表示樹的字符串,因此您可以在需要時打印它。字符串連接表示爲@。而你在函數中缺少的祕密成分叫做「模式匹配」。在這種情況下,您可以避免與if語句進行模式匹配。

讓我們做一個多態型第一:

datatype 'a btree = 
       Empty | 
       Node of 'a * 'a btree * 'a btree 

讓我們把這個功能多態:

fun displayTree T f = 
    case T of 
     Empty    => "" 
     |Node(root, left, right) => (f root)^(displayTree left f)^(displayTree right f) 

現在你必須定義函數f,你的匿名類型轉換爲string

讓我們更進一步,並定義返回節點值的列表,您可以打印相同的功能:

fun displayTree T f = 
    case T of 
     Empty    => [""] 
     |Node(root, left, right) => [f root] @ (displayTree left f) @ (displayTree right f) 

而且你可以把這個返回的unit的名單一:

fun displayTree T f = 
    case T of 
     Empty    => [print ""] 
     |Node(root, left, right) => [print(f root)] @ displayTree left f @ displayTree right f 

但我不明白你打算怎麼處理它們。

+0

我忘了提及我的'displayTree'函數是多態的。我只是在這個例子中顯示了一種類型。字符串連接是'^','@'是列表。 – user2803198

1

您的代碼有幾個問題,因此很難知道從哪裏開始。如果你想printInt實際上打印節點的值並返回單位那麼你不想對結果做任何事情。你應該簡單地丟棄它,並調用看起來應該像

(printInt root; displayTree left; displayTree right) 

您可能不需要let..in..end塊內的括號,但你需要的分號。

其他問題是您需要在樹上進行模式匹配。另外,通過在displayTree正文中包含printInt您只能打印int bTree類型的值。如果你想displayTree是多態的,你需要傳入一個函數來打印節點,因爲它將取決於節點的類型。如果節點是一個整數,但是其他類型的節點不是其他類型,則傳入的函數可能是printInt