2011-03-27 50 views
0

我試圖做一個功能,它允許我添加一個新的值到樹如果給定路徑的值等於ND(無數據),這是我的第一次嘗試。Haskell爲樹添加值

它檢查值等,但問題是,我想能夠打印修改後的樹與新的數據。任何人可以給我任何指針?我也嘗試做第​​二個函數,檢查路徑,看看它是否可以添加數據,但我只是失去了如何打印出修改過的樹?

+0

你看過IO monad嗎? – alternative 2011-03-27 16:53:27

+0

你可以添加更多的代碼嗎?例如,如何定義「BTree」? – fuz 2011-03-27 16:57:33

+0

現在沒有人會看看,我沒有被教過,所以不知道我的解決方案是否會使用它! – Lunar 2011-03-27 16:58:13

回答

5

正如iuliux指出的,您的問題在於您將BTree視爲可變結構。記住haskell中的函數需要參數並返回一個值。 That is all。所以,當你「映射」一個列表,或者遍歷一棵樹時,你的函數需要返回一棵新樹。

您擁有的代碼正在遍歷遞歸樹,並且僅返回最後一片葉。現在想象一下,在路徑末尾的葉子將總是ND。這是你想要什麼:

add :: a -> Path -> Btree a -> Btree a 
add da xs ND = Data da 
add _ [] _ = error "You should make sure this doesn't happen or handle it" 
add da (x:xs) (Branch st st2) = 
       case x of 
        L -> Branch (add da xs st) st2 
        R -> Branch st (add da xs st2) 

請注意,在你原來的代碼,你放棄對Branch您模式匹配,當你需要做的是恢復其「在你身後」,因爲它是。


現在,上的處理情況的問題,即你到達它的葉子是不是ND構造:

這種類型的問題是在函數式編程常見。當最終結果取決於樹下的一片樹葉時,如何「隨時」返回遞歸數據結構?

最棘手的情況下的一個解決方案是Zipper,這是一個數據結構,可以讓你隨心所欲地往上走。對於你的情況,這將是矯枉過正。

我建議你改變你的函數如下:

add :: a -> Path -> Btree a -> Maybe (Btree a) 

這意味着你必須返回一個Maybe (Btree a)每個級別。然後在遞歸調用中使用MaybeFunctor實例。注意:

fmap (+1) (Just 2) == Just 3 
fmap (+1) (Nothing) == Nothing 

你應該試着自己拼命執行它!

3

我不是Haskell的專家,但函數式編程只適用於函數。所以什麼都是功能。
現在,你的函數需要一些輸入並返回一些東西,而不是修改輸入。你必須從某個地方保留返回的樹,這將是你的新樹,一個用插入的元素在裏面

1

我們真的需要看到PathError數據類型來回答你的問題,但你可以打印出你的樹使用IO Monad:

main :: IO() 
main = do let b = Branch ND (Branch (Data 1) (Data 2)) 
      let b1 = add 10 [L] b --actual call depends on definition of Path 
      (putStrLn . show) b1