{-# LANGUAGE FlexibleInstances #-} module Combine where import Data.Semigroup import Test.QuickCheck newtype Combine a b = Combine { unCombine :: (a -> b) } instance Semigroup b => Semigroup (Combine a b) where (Combine f1) <> (Combine f2) = Combine f where f x = (f1 x) <> (f2 x) instance (Monoid b) => Monoid (Combine a b) where mempty = Combine $ \_ -> mempty mappend (Combine f1) (Combine f2) = Combine f where f x = mappend (f1 x) (f2 x) instance (Num a, CoArbitrary a, Arbitrary b) => Arbitrary (Combine a b) where arbitrary = do f <- arbitrary return $ Combine (\n -> f n) instance (Show a, Show b) => Show (Combine a b) where show _ = "a -> b"