0

Hi I need help in understanding this Foldable tree implementation from from here

Consider the following

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  

I have difficulty in understanding how in this example, mempty and mappend get their implementation what their types and how they infered from for example the following invokation.

F.foldl (+) 0 testTree 

Thanks

Boris
  • 1,311
  • 13
  • 39

1 Answers1

2

Check out the signature of foldMap:

foldMap :: Monoid m => (a -> m) -> t a -> m

See the Monoid m => constraint in there? It means that every time somebody calls foldMap, they have to choose a type m and provide an instance of Monoid for that type.

It's from that instance that mempty and mappend are coming. Since foldMap has been provided an instance of Monoid, it can call methods from that instance.

Fyodor Soikin
  • 78,590
  • 9
  • 125
  • 172
  • Thanks, but I am missing the link on how fold create the concrete instance of monoid – Boris Apr 26 '23 at 18:19
  • 2
    @Boris `foldMap` does not choose the monoid, the caller does. In practice, if you write `foldMap f x :: MyMonoidType`, annotating the call with an explicit monoid type of your choice, Haskell will use the corresponding monoid operations. This is not the only option, for instance the type `MyMonoidType` can often be inferred: `True : foldMap f x` will choose `[Bool]` as the monoid even without an explicit type annotation. – chi Apr 26 '23 at 19:51