你需要把東西放在一起不同,以實現自己的目標。您不能只用:
替換++
。試試這個:
toList t = toListPlus t []
toListPlus :: Tree a -> [a] -> [a]
toListPlus t xs
應該產生toList t ++ xs
,但遞歸調用實施toListPlus
,不使用++
或toList
。讓我們通過它。基本情況很容易:
toListPlus Empty xs = xs
遞歸情況也不算太差。我們希望將左側子樹轉換爲列表,並在其後粘貼其他內容:
toListPlus (Node v l r) xs =
toListPlus l ???
後來是什麼?根,然後將右子樹的結果,然後不管大幹快上上漲:
toListPlus (Node v l r) xs =
toListPlus l (v : toListPlus r xs)
此功能使用隱式堆棧跟蹤剩餘的工作。這可能是最有效的方法。如果你想要的話,你可以使用拉鍊風格的表示來顯示棧。
這個解決方案與左邊所描述的方法有什麼關係?那麼,他們實際上是一樣的。我們可以看到,通過移動列表參數:
toListPlus Empty = \xs -> xs
toListPlus (Node v l r)
= \xs -> toListPlus l (v : toListPlus r xs)
= toListPlus l . (v :) . toListPlus r
「:」和「++」具有不同的類型並且提供不同的功能。如果你願意,你可以寫'toList l ++(v:toList r)',但是你不能用':'來表示兩個列表。 – Mephy
@Mephy:正確。順便說一下,因爲「:」和「++」都是「infixr 5」,所以不需要。 – leftaroundabout
您需要*重新關聯* ++應用程序,直到每個應用程序的左操作數爲單例。然後你可以(基本上)用':'替換每個。 – dfeuer