Reputation: 825
I have my data type Pair
defined as
data Pair a b = Pair a b
I would like to make it a monoid. Here is my definition.
instance (Monoid a,Monoid b) => Monoid (Pair a b) where
mempty = Pair mempty mempty
mappend (Pair x1 y1) (Pair x2 y2) = Pair (mappend x1 x2) (mappend y1 y2)
However, I got the following error.
foldable.hs:3:10: error:
• Could not deduce (Semigroup (Pair a b))
arising from the superclasses of an instance declaration
from the context: (Monoid a, Monoid b)
bound by the instance declaration at foldable.hs:3:10-49
• In the instance declaration for ‘Monoid (Pair a b)’
|
3 | instance (Monoid a,Monoid b) => Monoid (Pair a b) where
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
What went wrong?
Upvotes: 2
Views: 270
Reputation: 7014
In the future GHC.Generics
will feature a Generically
wrapper which allows deriving both instances via Generically (Pair a b)
{-# Language DeriveGeneric #-}
{-# Language DerivingStrategies #-}
{-# Language DerivingVia #-}
import GHC.Generics
-- >> mempty @(Pair String ())
-- Pair "" ()
--
-- >> Pair "hello" () <> Pair " " undefined <> Pair "world" ()
-- Pair "hello world" ()
data Pair a b
deriving
stock Generic
deriving (Semigroup, Monoid)
via Generically (Pair a b)
This is already possible with generic-data.
Upvotes: 2
Reputation: 92117
mappend
is not really a method of Monoid anymore. You can implement it, but it should be just a synonym for (<>)
, which is in Semigroup, a superclass of Monoid. To implement Monoid, you must also implement Semigroup, and put your definition of mappend
there, named (<>)
.
Upvotes: 6