要实例化,Foldable您需要至少提供一个foldMap或的定义foldr。
data Tree a = Leaf | Node (Tree a) a (Tree a) instance Foldable Tree where foldMap f Leaf = mempty foldMap f (Node l x r) = foldMap f l `mappend` f x `mappend` foldMap f r foldr f acc Leaf = acc foldr f acc (Node l x r) = foldr f (f x (foldr f acc r)) l
此实现对树进行有序遍历。
ghci> let myTree = Node (Node Leaf 'a' Leaf) 'b' (Node Leaf 'c' Leaf) -- +--'b'--+ -- | | -- +-'a'-+ +-'c'-+ -- | | | | -- * * * * ghci> toList myTree "abc"
该DeriveFoldable扩展允许GHCFoldable根据类型的结构生成实例。我们可以通过调整Node构造函数的布局来改变机器遍历的顺序。
data Inorder a = ILeaf | INode (Inorder a) a (Inorder a) -- as before deriving Foldable data Preorder a = PrLeaf | PrNode a (Preorder a) (Preorder a) deriving Foldable data Postorder a = PoLeaf | PoNode (Postorder a) (Postorder a) a deriving Foldable -- injections from the earlier Tree type inorder :: Tree a -> Inorder a inorder Leaf = ILeaf inorder (Node l x r) = INode (inorder l) x (inorder r) preorder :: Tree a -> Preorder a preorder Leaf = PrLeaf preorder (Node l x r) = PrNode x (preorder l) (preorder r) postorder :: Tree a -> Postorder a postorder Leaf = PoLeaf postorder (Node l x r) = PoNode (postorder l) (postorder r) x ghci> toList (inorder myTree) "abc" ghci> toList (preorder myTree) "bac" ghci> toList (postorder myTree) "acb"