>返回二叉树的所有叶子非常简单:
data BinTree a = Empty | Node (BinTree a) a (BinTree a) deriving (Eq, Show)
getLeaves :: BinTree a -> [a]
getLeaves Empty = []
getLeaves (Node left current right) = [current]++getLeaves left++getLeaves right
但是,如果树不是二元的,而是多向树(即树中的每个节点可以有任意数量的子节点和叶子(呢?
data MWTree a = Empty | Node [MWTree a] deriving (Eq, Show)
我不是在寻找为我发布解决方案的人;我只是不确定哪些一般的Haskell概念可能值得学习来解决为这种类型的树编写getLeaves
的问题。
有兴趣看到这两种情况下的getLeaves
都可以以Foldable
或Traversable
的模式实现。 Foldable
toList :: Foldable f => f a -> [a]
编码了在Foldable
容器中收集所有值的想法f
。 Traversable
具有更强大的traverse :: (Applicative f, Traversable t) => (a -> t b) -> (f a -> t (f b))
,它编码了对Traversable
容器t
进行某种遍历的想法。 Traversable
意味着Foldable
newtype K b a = K { unK :: b } deriving Functor
instance Monoid b => Applicative (K b) where
pure = K mempty
K e <*> K f = K (e <> f)
foldMapDefault :: (Traversable t, Monoid m) => (a -> m) -> (t a -> m)
foldMapDefault f = unK . traverse (K . f)
我认为您的代码中存在错误,您将树的所有节点添加到叶子列表中,这是错误的,您需要检查某个节点是否是叶子,然后才能将其添加到列表中。
data BinTree a = Empty | Node (BinTree a) a (BinTree a) deriving (Eq, Show)
getLeaves :: BinTree a -> [a]
getLeaves Empty = []
getLeaves (Node Empty current Empty) = [current]
getLeaves (Node left current right) = getLeaves left++getLeaves right
对于非二叉树也是如此(我认为您的代码中也存在错误(
data MWTree a = Empty | Node a [MWTree a] deriving (Eq, Show)
getLeaves :: (Eq a) => MWTree a -> [a]
getLeaves Empty = []
getLeaves (Node current []) = [current]
getLeaves (Node current children) = if all (==Empty) children
then [current]
else (children >>= getLeaves)
--else concat $ map getLeaves children (another way of writing the same thing)