Depth of a tree (Haskell)

前端 未结 3 716
灰色年华
灰色年华 2021-01-23 16:25

I\'m trying to figure out how to calculate the depth of a general tree in Haskell. I can figure out the solution for simple binary trees, but not for general trees with any numb

3条回答
  •  感动是毒
    2021-01-23 16:31

    Think about generalizing the pattern to lists:

    data Tree a = Node a [Tree a] | Nil
    
    depth Nil = 0
    depth (Node _ [a]) = 1 + depth a
    depth (Node _ [a,b]) = 1 + max (depth a) (depth b)
    depth (Node _ [a,b,c]) = 1 + max (max (depth a) (depth b)) (depth c)
    etc...
    

    Well, all you are doing is finding the depth of each subtree (map depth), then finding the maximum of those numbers (maximum):

    depth Nil = 0
    depth (Node _ a) = 1 + maximum (map depth a)
    

    You can flatten the tree in the same way, just map over the subtrees:

    treeToList (Node n a) = n : concat (map treeToList a)
    

    You have to use concat because map collapse returns a list of lists and you just want a list. Alternatively, you can define an instance for the Foldable typeclass and you automatically get toList :: Foldable t => t a -> [a]

    import Data.Foldable
    import Data.Monoid
    
    instance Foldable Tree where 
      foldMap f Nil = mempty
      foldMap f (Node a n) = f a `mappend` mconcat (map foldMap n)
    

    If you scrutinize the definition of foldMap very carefully, you will see that it is just a more general treeToList, where : is replaced by mappend and [] by mempty. Then it is logical that you can write treeToList in terms of the monoid ([], ++):

    data List a = List {getList :: [a]}
    instance Monoid (List a) where 
      mempty = List []
      mappend (List a) (List b) = List (a ++ b)
    
    treeToList = getList . foldMap (List . (:[]))
    

提交回复
热议问题