I'm working through the online LYAH book (the link will take you directly to the section that my question concerns).
The author defines a binary tree data type, and shows how it can be made an instance of the type Foldable (defined in Data.Foldable) by implementing the foldMap function:
import Data.Monoid
import qualified Data.Foldable as F
data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)
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
The type declaration of foldMap is as follows:
F.foldMap :: (Monoid m, F.Foldable t) => (a -> m) -> t a -> m
so it takes a function that takes an instance of type "a" and returns a monoid.
Now as an example, the author creates a Tree instance
testTree = Node 5
(Node 3
(Node 1 Empty Empty)
(Node 6 Empty Empty)
)
(Node 9
(Node 8 Empty Empty)
(Node 10 Empty Empty)
)
and performs the following fold (defined for Foldable types):
F.foldl (+) 0 testTree -- the answer is 42 (sum of the Node Integers)
My question is, how does Haskell figure out that addition over the Integer type - querying Haskell for the type of testTree gives Tree [Integer] - can be viewed as a monoid operation (if my terminology is correct)?
(My own attempt at the answer: The author a few paragraphs before this section describes how the Num type can be interpreted as a Monoid type in two different ways; by wrapping them into the Sum and Product type with (+) and (*) as the mappend functions and 0 and 1 as the mempty element, respectively. Is the type of "a" in (Tree a) somehow being inferred as belonging to the Sum type (the way Haskell variously interprets numerical values according to the context) or is it something else entirely? ]