title: Foldable and Monoid types
body: <p>I'm trying to write functions that add and multiply all elements in a list using monoids and Foldable. I've set up some code that I think works:</p>
  
  <pre><code>data Rose a = a :&gt; [Rose a]
      deriving (Eq, Show)
  
  instance Functor Rose where
      fmap f rose@(a:&gt;b) = (f a :&gt; map (fmap f) b) 
  
  class Monoid a where
      mempty ::           a
      (&lt;&gt;)   :: a -&gt; a -&gt; a
  
  instance Monoid [a] where
      mempty = []
      (&lt;&gt;)   = (++)
  
  newtype Sum     a = Sum     { unSum     :: a } deriving (Eq, Show)
  newtype Product a = Product { unProduct :: a } deriving (Eq, Show)
  
  instance Num a =&gt; Monoid (Sum a) where
      mempty           = Sum 0
      Sum n1 &lt;&gt; Sum n2 = Sum (n1 + n2)
  
  instance Num a =&gt; Monoid (Product a) where
      mempty                   = Product 1
      Product n1 &lt;&gt; Product n2 = Product (n1 * n2)
  
  class Functor f =&gt; Foldable f where
      fold    :: Monoid m =&gt;             f m -&gt; m
      foldMap :: Monoid m =&gt; (a -&gt; m) -&gt; f a -&gt; m
      foldMap f a = fold (fmap f a)
  
  instance Foldable [] where
      fold = foldr (&lt;&gt;) mempty
  
  instance Foldable Rose where
      fold (a:&gt;[]) = a &lt;&gt; mempty
      fold (a:&gt;b)  = a &lt;&gt; (fold (map fold b))
  </code></pre>
  
  <p>And then after having defined the different Foldable instances and the Sum and Product types I want to define two functions that add respectively multiply the elements in a datastructure, but this gives errors which I do not know how to interpret, I must admit that I it was more guess work than actual logic so a thorough explanation of your answer would be welcome.</p>
  
  <pre><code>fsum, fproduct :: (Foldable f, Num a) =&gt; f a -&gt; a
  fsum b     = foldMap Sum b
  fproduct b = foldMap Product b
  </code></pre>
  
  <p>Error:</p>
  
  <pre><code>Assignment3.hs:68:14: error:
      * Occurs check: cannot construct the infinite type: a ~ Sum a
      * In the expression: foldMap Sum b
        In an equation for `fsum': fsum b = foldMap Sum b
      * Relevant bindings include
          b :: f a (bound at Assignment3.hs:68:6)
          fsum :: f a -&gt; a (bound at Assignment3.hs:68:1)
     |
  68 | fsum b     = foldMap Sum b
     |              ^^^^^^^^^^^^^
  
  Assignment3.hs:69:14: error:
      * Occurs check: cannot construct the infinite type: a ~ Product a
      * In the expression: foldMap Product b
        In an equation for `fproduct': fproduct b = foldMap Product b
      * Relevant bindings include
          b :: f a (bound at Assignment3.hs:69:10)
          fproduct :: f a -&gt; a (bound at Assignment3.hs:69:1)
     |
  69 | fproduct b = foldMap Product b
     |              ^^^^^^^^^^^^^^^^^
  </code></pre>