module Two where import Data.Semigroup import Test.QuickCheck data Two a b = Two a b deriving (Eq, Show) data Three a b c = Three a b c deriving (Eq, Show) data Four a b c d = Four a b c d deriving (Eq, Show) instance (Semigroup a, Semigroup b) => Semigroup (Two a b) where (Two x1 y1) <> (Two x2 y2) = Two (x1 <> x2) (y1 <> y2) instance (Monoid a, Monoid b) => Monoid (Two a b) where mempty = Two mempty mempty mappend (Two x1 y1) (Two x2 y2) = Two (mappend x1 x2) (mappend y1 y2) instance (Arbitrary a, Arbitrary b) => Arbitrary (Two a b) where arbitrary = do x <- arbitrary y <- arbitrary return $ Two x y instance (Semigroup a, Semigroup b, Semigroup c) => Semigroup (Three a b c) where (Three x1 y1 z1) <> (Three x2 y2 z2) = Three (x1 <> x2) (y1 <> y2) (z1 <> z2) instance (Monoid a, Monoid b, Monoid c) => Monoid (Three a b c) where mempty = Three mempty mempty mempty mappend (Three x1 y1 z1) (Three x2 y2 z2) = Three (mappend x1 x2) (mappend y1 y2) (mappend z1 z2) instance (Arbitrary a, Arbitrary b, Arbitrary c) => Arbitrary (Three a b c) where arbitrary = do x <- arbitrary y <- arbitrary z <- arbitrary return $ Three x y z instance (Semigroup a, Semigroup b, Semigroup c, Semigroup d) => Semigroup (Four a b c d) where (Four x1 y1 z1 t1) <> (Four x2 y2 z2 t2) = Four (x1 <> x2) (y1 <> y2) (z1 <> z2) (t1 <> t2) instance (Monoid a, Monoid b, Monoid c, Monoid d) => Monoid (Four a b c d) where mempty = Four mempty mempty mempty mempty mappend (Four x1 y1 z1 t1) (Four x2 y2 z2 t2) = Four (mappend x1 x2) (mappend y1 y2) (mappend z1 z2) (mappend t1 t2) instance (Arbitrary a, Arbitrary b, Arbitrary c, Arbitrary d) => Arbitrary (Four a b c d) where arbitrary = do x <- arbitrary y <- arbitrary z <- arbitrary t <- arbitrary return $ Four x y z t