返回二叉树的所有叶子很简单:
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
的问题。
答案 0 :(得分:2)
您可能有兴趣看到两种情况下的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)
答案 1 :(得分:2)
我认为您的代码中存在错误,您将树的所有节点添加到叶子列表中,这是错误的,您需要先检查某个节点是否为叶子,然后才能将其添加到叶子中清单。
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)