Reputation: 742
I am learning Haskell with the help of "http://learnyouahaskell.com". I am following the example of a BST (Binary Search Tree) that is an instance of Foldable
:
data Tree a = Nil | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)
instance F.Foldable Tree where
foldMap f Nil = mempty
foldMap f (Node x l r) = (F.foldMap f l) `mappend` (f x) `mappend` (F.foldMap f r)
When I run F.foldMap (\x -> [x]) testTree
I get a list that represents the folded tree.
I implemented my own data type:
newtype OnlySum a = OnlySum {value :: a} deriving (Eq, Ord, Read, Show, Bounded)
instance Num a => Monoid (OnlySum a) where
mempty = OnlySum 0
OnlySum x `mappend` OnlySum y = OnlySum (x + y)
And ran this command: F.foldMap (\x -> OnlySum x) testTree
to obtain the tree folded as this OnlySum {value = 34}
.
The question is: How does Foldable know the definition of mempty
and mappend
depending on the return type of the function f
passed to foldMap
? Does it infer it or is there a way for Haskell to automatically know which is the definition?
Upvotes: 1
Views: 177
Reputation: 17431
In the definition of foldMap we see that it requires a typeclass instance Monoid m
. So Haskell knows that mappend
is coming from Monoid
. The specific type will be inferred, then a Monoid
typeclass instance resolved based on that type, and that typeclass is what will be used.
Upvotes: 3