我正在通过 Learn You a Haskell 进行工作,并且我在 monoids 部分。在本节中,作者为一棵树定义 foldMap 方法如下:
instance F.Foldable Tree where
foldMap f Empty = mempty
foldMap f (Node x l r) = F.foldMap f l `mappend`
f x `mappend`
F.foldMap f r
哪个工作正常,完全是芭蕾舞者。然而,他接着说“现在我们的树类型有一个可折叠的实例,我们可以免费获得 foldr 和 foldl!” 并显示以下代码:
testTree = Node 5
(Node 3
(Node 1 Empty Empty)
(Node 6 Empty Empty)
)
(Node 9
(Node 8 Empty Empty)
(Node 10 Empty Empty)
)
ghci> F.foldl (+) 0 testTree
42
ghci> F.foldl (*) 1 testTree
64800
现在我很困惑。没有任何地方是为 Trees 编写的 foldl 或 foldr 实现。这些函数似乎有点像 foldmap,但是将初始累加器作为树的头部,然后 foldMapping 在适当的幺半群上,但它实际上不能像这样工作,因为 foldl 和 foldr 比幺半群 '+' 和 '*' 作为参数。foldl 和 foldr 实际在哪里实现,它们是如何工作的,为什么定义 foldMap 会导致它们存在?