{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -Wno-orphans #-} module TestBiBarbies ( Record0(..) , Record1(..) , Record3(..) , Record1S(..) , Record3S(..) , Ignore1(..) , Sum3(..) , CompositeRecord(..) , SumRec(..) , InfRec(..) , NestedF(..) , Nested2F(..) , ParX(..) , HKB(..) , NestedB(..) , MixedBT(..) ) where import Barbies import Data.Distributive import qualified TestBarbies import Data.Kind(Type) import Data.Typeable import GHC.Generics import Test.Tasty.QuickCheck instance Arbitrary (b r l) => Arbitrary (Barbies.Flip b l r) where arbitrary = Barbies.Flip <$> arbitrary ---------------------------------------------------- -- Product Barbies ---------------------------------------------------- data Record0 (f :: kl -> Type) (x :: kr) = Record0 deriving ( Generic, Typeable , Eq, Show ) instance FunctorT Record0 instance DistributiveT Record0 instance ApplicativeT Record0 instance TraversableT Record0 instance ConstraintsT Record0 instance Arbitrary (Record0 f g) where arbitrary = pure Record0 data Record1 f (x :: kr) = Record1 { rec1_f1 :: f Int } deriving (Generic, Typeable) instance FunctorT Record1 instance DistributiveT Record1 instance ApplicativeT Record1 instance TraversableT Record1 instance ConstraintsT Record1 deriving instance AllTF Show f Record1 => Show (Record1 f x) deriving instance AllTF Eq f Record1 => Eq (Record1 f x) instance AllTF Arbitrary f Record1 => Arbitrary (Record1 f g) where arbitrary = Record1 <$> arbitrary data Record1S f (x :: kr) = Record1S { rec1s_f1 :: !(f Int) } deriving (Generic, Typeable) instance FunctorT Record1S instance DistributiveT Record1S instance ApplicativeT Record1S instance TraversableT Record1S instance ConstraintsT Record1S deriving instance AllTF Show f Record1S => Show (Record1S f x) deriving instance AllTF Eq f Record1S => Eq (Record1S f x) instance AllTF Arbitrary f Record1S => Arbitrary (Record1S f x) where arbitrary = Record1S <$> arbitrary data Record3 f x = Record3 { rec3_f1 :: f Int , rec3_f2 :: f Bool , rec3_f3 :: f Char , rec3_m1 :: Maybe () } deriving (Generic, Typeable) instance FunctorT Record3 instance ApplicativeT Record3 instance TraversableT Record3 instance ConstraintsT Record3 deriving instance AllTF Show f Record3 => Show (Record3 f x) deriving instance AllTF Eq f Record3 => Eq (Record3 f x) instance AllTF Arbitrary f Record3 => Arbitrary (Record3 f x) where arbitrary = Record3 <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary data Record3S f x = Record3S { rec3s_f1 :: !(f Int) , rec3s_f2 :: !(f Bool) , rec3s_f3 :: !(f Char) } deriving (Generic, Typeable) instance FunctorT Record3S instance DistributiveT Record3S instance ApplicativeT Record3S instance TraversableT Record3S instance ConstraintsT Record3S deriving instance AllTF Show f Record3S => Show (Record3S f x) deriving instance AllTF Eq f Record3S => Eq (Record3S f x) instance AllTF Arbitrary f Record3S => Arbitrary (Record3S f x) where arbitrary = Record3S <$> arbitrary <*> arbitrary <*> arbitrary ----------------------------------------------------- -- Bad products ----------------------------------------------------- data Ignore1 (f :: Type -> Type) (x :: kx) = Ignore1 { ign1_f1 :: Int } deriving (Generic, Typeable, Eq, Show) instance FunctorT Ignore1 instance TraversableT Ignore1 instance ConstraintsT Ignore1 instance Arbitrary (Ignore1 f x) where arbitrary = Ignore1 <$> arbitrary ----------------------------------------------------- -- Sums ----------------------------------------------------- data Sum3 f x = Sum3_0 | Sum3_1 (f Int) | Sum3_2 (f Int) (f Bool) deriving (Generic, Typeable) instance FunctorT Sum3 instance TraversableT Sum3 instance ConstraintsT Sum3 deriving instance AllTF Show f Sum3 => Show (Sum3 f x) deriving instance AllTF Eq f Sum3 => Eq (Sum3 f x) instance AllTF Arbitrary f Sum3 => Arbitrary (Sum3 f x) where arbitrary = oneof [ pure Sum3_0 , Sum3_1 <$> arbitrary , Sum3_2 <$> arbitrary <*> arbitrary ] ----------------------------------------------------- -- Composite and recursive ----------------------------------------------------- data CompositeRecord f x = CompositeRecord { crec_f1 :: f Int , crec_F2 :: f Bool , crec_f3 :: Record3 f x , crec_f4 :: Record1 f x } deriving (Generic, Typeable) instance FunctorT CompositeRecord instance ApplicativeT CompositeRecord instance TraversableT CompositeRecord instance ConstraintsT CompositeRecord deriving instance AllTF Show f CompositeRecord => Show (CompositeRecord f x) deriving instance AllTF Eq f CompositeRecord => Eq (CompositeRecord f x) instance AllTF Arbitrary f CompositeRecord => Arbitrary (CompositeRecord f x) where arbitrary = CompositeRecord <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary data SumRec f x = SumRec_0 | SumRec_1 (f Int) | SumRec_2 (f Int) (SumRec f x) deriving (Generic, Typeable) instance FunctorT SumRec instance TraversableT SumRec instance ConstraintsT SumRec deriving instance AllTF Show f SumRec => Show (SumRec f x) deriving instance AllTF Eq f SumRec => Eq (SumRec f x) instance AllTF Arbitrary f SumRec => Arbitrary (SumRec f x) where arbitrary = oneof [ pure SumRec_0 , SumRec_1 <$> arbitrary , SumRec_2 <$> arbitrary <*> arbitrary ] data InfRec f x = InfRec { ir_1 :: f Int, ir_2 :: InfRec f x } deriving (Generic, Typeable) instance FunctorT InfRec instance ApplicativeT InfRec instance TraversableT InfRec instance ConstraintsT InfRec deriving instance AllTF Show f InfRec => Show (InfRec f x) deriving instance AllTF Eq f InfRec => Eq (InfRec f x) ----------------------------------------------------- -- Nested under functors ----------------------------------------------------- data NestedF f x = NestedF { npf_1 :: f Int , npf_2 :: [Record3 f x] , npf_3 :: Maybe (NestedF f x) } deriving (Generic, Typeable) instance FunctorT NestedF instance ApplicativeT NestedF instance TraversableT NestedF deriving instance (Show (f Int), Show (Record3 f x)) => Show (NestedF f x) deriving instance (Eq (f Int), Eq (Record3 f x)) => Eq (NestedF f x) instance (Arbitrary (f Int), AllTF Arbitrary f Record3, AllTF Arbitrary f Sum3) => Arbitrary (NestedF f x) where arbitrary = scale (`div` 2) $ NestedF <$> arbitrary <*> scale (`div` 2) arbitrary <*> arbitrary data Nested2F f x = Nested2F { np2f_1 :: f Int , np2f_2 :: [Maybe (Nested2F f x)] } deriving (Generic, Typeable) instance FunctorT Nested2F instance TraversableT Nested2F instance ApplicativeT Nested2F deriving instance Show (f Int) => Show (Nested2F f x) deriving instance Eq (f Int) => Eq (Nested2F f x) instance Arbitrary (f Int) => Arbitrary (Nested2F f x) where arbitrary = scale (`div` 2) $ Nested2F <$> arbitrary <*> scale (`div` 2) arbitrary ----------------------------------------------------- -- Parametric barbies ----------------------------------------------------- data ParB b (f :: k -> Type) (x :: kx) = ParB (b f x) deriving (Generic, Typeable) instance FunctorT b => FunctorT (ParB b) instance DistributiveT b => DistributiveT (ParB b) instance ApplicativeT b => ApplicativeT (ParB b) instance TraversableT b => TraversableT (ParB b) instance ConstraintsT b => ConstraintsT (ParB b) data ParBH h b (f :: k -> Type) (x :: kx) = ParBH (h (b f x)) deriving (Generic, Typeable) instance (Functor h, FunctorT b) => FunctorT (ParBH h b) instance (Distributive h, DistributiveT b) => DistributiveT (ParBH h b) instance (Applicative h, ApplicativeT b) => ApplicativeT (ParBH h b) instance (Traversable h, TraversableT b) => TraversableT (ParBH h b) data ParX a f x = ParX (f a) a deriving (Generic, Typeable) instance FunctorT (ParX a) instance Monoid a => ApplicativeT (ParX a) instance TraversableT (ParX a) instance ConstraintsT (ParX a) deriving instance (Show a, Show (f a)) => Show (ParX a f x) deriving instance (Eq a, Eq (f a)) => Eq (ParX a f x) instance (Arbitrary a, Arbitrary (f a)) => Arbitrary (ParX a f x) where arbitrary = ParX <$> arbitrary <*> arbitrary ----------------------------------------------------- -- Higher-kinded barbies ----------------------------------------------------- data HKB b x = HKB { hkb1 :: b Maybe , khb2 :: b ([]) } deriving (Generic, Typeable) instance FunctorT HKB instance ApplicativeT HKB instance TraversableT HKB instance ConstraintsT HKB ----------------------------------------------------- -- Actual bi-barbies ----------------------------------------------------- type Record1' = TestBarbies.Record1 data NestedB f g = NestedB { nb_1 :: g Int , nb_2 :: f (g Bool) , nb_3 :: f (Record1' g) , nb_4 :: Record1' g } deriving (Generic, Typeable) instance FunctorT NestedB instance TraversableT NestedB instance Functor f => FunctorB (NestedB f) instance Distributive f => DistributiveB (NestedB f) instance Applicative f => ApplicativeB (NestedB f) instance Traversable f => TraversableB (NestedB f) deriving instance (Show (f (g Bool)), AllBF Show g Record1', Show (f (Record1' g))) => Show (NestedB f g) deriving instance (Eq (f (g Bool)), AllBF Eq g Record1', Eq (f (Record1' g))) => Eq (NestedB f g) instance (Arbitrary (f (g Bool)), AllBF Arbitrary g Record1', Arbitrary (f (Record1' g))) => Arbitrary (NestedB f g) where arbitrary = NestedB <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary data MixedBT f g = MixedBT { mx_1 :: f Int , mx_2 :: g Bool } deriving (Generic, Typeable) instance FunctorT MixedBT instance TraversableT MixedBT instance ConstraintsT MixedBT instance FunctorB (MixedBT f) instance (Monoid (f Int)) => ApplicativeB (MixedBT f) instance TraversableB (MixedBT f) instance ConstraintsB (MixedBT f) deriving instance (AllBF Show g (MixedBT f), AllTF Show f MixedBT) => Show (MixedBT f g) deriving instance (AllBF Eq g (MixedBT f), AllTF Eq f MixedBT) => Eq (MixedBT f g) instance (AllBF Arbitrary g (MixedBT f), AllTF Arbitrary f MixedBT) => Arbitrary (MixedBT f g) where arbitrary = MixedBT <$> arbitrary <*> arbitrary