As the title says, I need this:
getAllTrees :: [Int] -> [Tree Int]
getAllTrees xs = undefined
where tree is
data Tree x
= Null
| Leaf x
| Node (Tree x) x (Tree x)
I will appreciate any help, even the smallest clue 🙂
Thanks
I usually find it easiest to use the list monad for these kinds of problems. We can define
getAllTreesby reasoning as follows:The only tree of zero items is
Null:There is also only one tree of one element, namely a
Leaf:When we have more than one element, we can split the list in all possible ways to determine how we should branch, and then recursively generate the sub-trees from each list. Let’s say we have a function
splits :: [a] -> [([a], [a])]that returns all ways of splitting a list, for example:We can then define the final case of
getAllTreesby using the list monad. This allows us to write code which sort of looks like like we’re focusing on only one case, and the monad will give us all the combinations.The first line splits the input list and takes the first item from the second part as the middle element. The case when the second part is empty doesn’t match the pattern, so it gets discarded since that’s how the list monad handles pattern match failures.
The second line uses applicative syntax to say that we want the result to be a list of nodes, made from all combinations of sub-trees from the
leftlist, the fixed middle elementx, and all sub-trees from therightlist.All that remains then is to implement
splits. Looking at the example above, it’s easy to see that we can just take theinitsandtailsof the list andzipthem together:Time for a quick sanity check in the interpreter:
Looks like we’re done! Some key lessons: