Lee Lee Lee
Lee Lee Lee

Reputation: 45

How to fix "Could not deduce (Num (Sum a)) arising from a use of ‘+’"?

I took code from this lecture, but I got an error with the demo code below:

newtype Sum a = Sum a
  deriving (Eq,Ord,Show)
getSum::Sum a -> a
getSum (Sum a) = a
instance Num a=>Monoid (Sum a)where
  mempty = Sum 0
  mappend = (+)
newtype  Product a = Product a
  deriving (Eq,Ord,Show)
getProduct ::Product a -> a
getProduct (Product a ) = a
instance Num a => Monoid (Product a ) where
  mempty = Product 1
  mappend = (*)

I got the following error message (with GHC 8.2.2):

Test.hs:40:13: error:
       ? Could not deduce (Num (Sum a)) arising from a use of ‘+’
         from the context: Num a
           bound by the instance declaration at Test.hs:38:10-30
       ? In the expression: (+)
         In an equation for ‘mappend’: mappend = (+)
         In the instance declaration for ‘Monoid (Sum a)’   
 | 40 |   mappend = (+)  

Test.hs:50:13: error:
    ? Could not deduce (Num (Product a)) arising from a use of ‘*’
      from the context: Num a
        bound by the instance declaration at Test.hs:48:10-37
    ? In the expression: (*)
      In an equation for ‘mappend’: mappend = (*)
      In the instance declaration for ‘Monoid (Product a)’
50 |   mappend = (*)

Upvotes: 0

Views: 209

Answers (1)

Adam Smith
Adam Smith

Reputation: 54213

By defining mappend as (+), you're saying that Sum a is itself a member of Num. Rather, it only contains those members, so (+) should operate on those members.

instance Num a => Monoid (Sum a) where
    mempty                  = Sum 0
    mappend (Sum x) (Sum y) = Sum $ x + y

Likewise for Product

instance Num a => Monoid (Product a) where
    mempty                          = Product 1
    mappend (Product x) (Product y) = Product $ x * y

Then your monoid instances work as expected.

xs = map Sum [1..5]
ys = map Product [1..5]
mconcat xs  -- 15
mconcat ys  -- 120

Alternatively you could follow the lecture's code and derive Num in your newtypes.

-- from the linked lecture
newtype Sum a = Sum a
  deriving (Eq, Ord, Num, Show)
newtype Product a = Product a
  deriving (Eq, Ord, Num, Show)

Upvotes: 3

Related Questions