查找项目是否包含在k-ary树中

时间:2009-11-11 23:26:43

标签: haskell tree

我有数据类型

data KTree a = Empty | Leaf a | Node a [KTree a] deriving (Eq, Show)

我想编写一个函数,该函数返回true或false,以确定项目是否包含在我的树中。

ktreeContains :: Eq a => a -> (KTree a) -> Bool
ktreeContains _ Empty = False
ktreeContains y (Leaf x) = (x==y)
-- code for nodes goes here

所以我意识到我需要找到节点本身是否是项目,然后递归调用节点子节点的ktreeContains但我不明白如何做到这一点,因为每个节点可以有很多子节点。

我认为到目前为止我所拥有的代码是正确的,但如果没有,请随时纠正我。

感谢任何帮助,谢谢。

3 个答案:

答案 0 :(得分:3)

ktreeContains y (Node x ts) = x == y || any (ktreeContains y) ts

只是出于兴趣,Leaf xNode x []之间有什么区别?

答案 1 :(得分:2)

ktreeContains y (Node x ts) = x == y || (any . ktreeContains) y ts

答案 2 :(得分:1)

我很无聊所以我决定使用Data.Foldable类型类推广解决方案。

import Data.Monoid
import Data.Foldable hiding (any)

data KTree a = Empty | Leaf a | Node a [KTree a] deriving (Ord, Eq, Show)

ktreeContains :: Eq a => a -> (KTree a) -> Bool
ktreeContains _ Empty = False
ktreeContains y (Leaf x) = (x==y)
-- code for nodes goes here
ktreeContains y (Node x ts) = x == y || any (ktreeContains y) ts

example1 = Empty
example2 = Leaf 1
example3 = Node 1 [Leaf 2]
example4 = Node 2 [Leaf 1, Node 4 [Leaf 5, Leaf 3]]

ktreeContainsF :: Eq a => a -> KTree a -> Bool
ktreeContainsF y = getAny . foldMap (Any.(==y))

instance Foldable KTree where
    foldMap f (Empty) = mempty
    foldMap f (Leaf a) = f a
    -- work out a possible ordering thats better than this
    -- it works for now since we are only dealing with Equality
    foldMap f (Node a x) = f a `mappend` (mconcat . map (foldMap f)) x

ktreeContainsktreeContainsF是相同的函数,但ktreeContainsF KTree的遍历由Data.Foldable类处理。由于foldMap会返回Monoid,因此可以使用Any monoid来合并搜索结果。


如果有助于更好地理解这一点,ktreeContainsFktreeContainsMonoid的更通用版本,定义为

ktreeContainsMonoid y = getAny . Data.Foldable.foldl
        -- combination function, implicit when using FoldMap
        (\z x-> z `mappend` Any (x == y)) mempty -- also implicit in foldMap