我試圖做一個功能,它允許我添加一個新的值到樹如果給定路徑的值等於ND(無數據),這是我的第一次嘗試。Haskell爲樹添加值
它檢查值等,但問題是,我想能夠打印修改後的樹與新的數據。任何人可以給我任何指針?我也嘗試做第二個函數,檢查路徑,看看它是否可以添加數據,但我只是失去了如何打印出修改過的樹?
我試圖做一個功能,它允許我添加一個新的值到樹如果給定路徑的值等於ND(無數據),這是我的第一次嘗試。Haskell爲樹添加值
它檢查值等,但問題是,我想能夠打印修改後的樹與新的數據。任何人可以給我任何指針?我也嘗試做第二個函數,檢查路徑,看看它是否可以添加數據,但我只是失去了如何打印出修改過的樹?
正如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)
每個級別。然後在遞歸調用中使用Maybe
的Functor
實例。注意:
fmap (+1) (Just 2) == Just 3
fmap (+1) (Nothing) == Nothing
你應該試着自己拼命執行它!
我不是Haskell的專家,但函數式編程只適用於函數。所以什麼都是功能。
現在,你的函數需要一些輸入並返回一些東西,而不是修改輸入。你必須從某個地方保留返回的樹,這將是你的新樹,一個用插入的元素在裏面
我們真的需要看到Path
和Error
數據類型來回答你的問題,但你可以打印出你的樹使用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
你看過IO monad嗎? – alternative 2011-03-27 16:53:27
你可以添加更多的代碼嗎?例如,如何定義「BTree」? – fuz 2011-03-27 16:57:33
現在沒有人會看看,我沒有被教過,所以不知道我的解決方案是否會使用它! – Lunar 2011-03-27 16:58:13