为Trie实现可折叠

时间:2013-01-30 15:42:30

标签: haskell trie

我想让我的Trie数据结构可折叠。基本数据结构如下所示:

data Trie a = Trie {
    value :: Maybe a,
    children :: [(Char, Trie a)]
} deriving (Show)

我尝试通过定义foldr来实现Foldable类:

instance F.Foldable Trie where
    foldr f z (Trie (Just v) children) =
        F.foldr (\a b -> F.foldr f b a) (f v z) children

    foldr f z (Trie Nothing children) =
        F.foldr (\a b -> F.foldr f b a) z children

这不会编译此错误:

Couldn't match type `a' with `Trie a'
  `a' is a rigid type variable bound by
      the type signature for foldr :: (a -> b -> b) -> b -> Trie a -> b
      at Trie.hs:17:5
Expected type: [(Char, a)]
  Actual type: [(Char, Trie a)]
In the third argument of `F.foldr', namely `children'
In the expression:
  F.foldr (\ a b -> F.foldr f b a) (f v z) children

但是,如果我将子项类型更改为Map Char (Trie a),则可折叠实现无需更改即可运行。为了简单起见,我想保留关联列表。你能解释一下为什么foldr在地图和关联列表上表现不同吗?

1 个答案:

答案 0 :(得分:3)

错误是因为您试图折叠键值列表 对,而不是Trie的列表。你想要做的是忽略Char 键,只是折叠到每个子节点,如此

foldr f z (Trie (Just v) children) =
    F.foldr (\(_, a) b -> F.foldr f b a) (f v z) children

foldr f z (Trie Nothing children) =
    F.foldr (\(_, a) b -> F.foldr f b a) z children