我想让我的 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)
,则 Foldable 实现无需更改即可工作。为了简单起见,我现在想保留关联列表。你能解释一下为什么 foldr 在地图和关联列表上的行为不同吗?