1

I would like to flatten a tree which looks like this:

> data Tree a =  Leaf a
>              | Fork a [Tree a]
>              | Root [Tree a]

possible example:

Root [Fork 'a' [Fork 'b' [Leaf 'c'],Fork 'c' [Leaf 'b']],Fork 'b' [Fork 'a' [Leaf 'c'],Fork 'c' [Leaf 'a']],Fork 'c' [Fork 'a' [Leaf 'b'],Fork 'b' [Leaf 'a']]]

should become

["abc","acb","bac","bca","cab","cba"]

To explain why: I try to build kind of a permutation Tree. I wrote a function permute :: String -> Tree Char to visualize all possible permutations of an string into a Tree. But I dont get how to flatten this kind of tree. Thank you for help.

duplode
  • 33,731
  • 7
  • 79
  • 150
homior
  • 161
  • 1
  • 12
  • 3
    Any particular reason why Root is distinct from Fork? Usually you just would have Fork and Leaf, because Root is only the root out of convention here. – HTNW Feb 26 '18 at 18:30
  • @HTNW It makes some sense for the OP's use case -- in their example, for instance, there should be three "top" nodes at the same level. In any case, the type can definitely be simplified -- with some adjustments, `Data.Tree` from *containers* would do the trick. – duplode Feb 27 '18 at 03:25
  • 1
    (@homior Explaining a bit better: it is possible to leave out both the `Leaf` constructor (use `Fork`s with an empty list of trees instead) and the `Root` one (make the result of `permute` a list of trees instead). Your `Tree` would then become equivalent to the one from [`Data.Tree`](https://hackage.haskell.org/package/containers-0.5.11.0/docs/Data-Tree.html).) – duplode Feb 27 '18 at 03:49

1 Answers1

4

My approach here comes out to a depth first search.

data Tree a =  Leaf a          
            | Fork a [Tree a]       
            | Root [Tree a]         
            deriving(Show)

dfs :: Tree a -> [[a]]
dfs (Root ts) = concatMap dfs ts
dfs (Fork v ts) = map (v:) (concatMap dfs ts) 
dfs (Leaf v) = [[v]]
DTown
  • 141
  • 5