git.iko.soy/typeable/generic-arbitrary
on master help sign in
parameterized types
commit0a1f9dc51edcfe65573c95c88bc32b94f8b10d3c authorAleksey Uymanov <s9gf4ult@gmail.com> dateTue 3 Aug 2021, 17:36 (5 years ago) parent926d869
3 files changed+22−4
generic-arbitrary.cabal+1 src/Test/QuickCheck/Arbitrary/Generic.hs+9−4 test/RecursiveTest.hs+12
generic-arbitrary.cabal+1
@@ -35,6 +35,7 @@ library
3535 default-language: Haskell2010
3636 default-extensions: AllowAmbiguousTypes
3737 , CPP
38+ , ConstraintKinds
3839 , DataKinds
3940 , DeriveGeneric
4041 , FlexibleContexts
src/Test/QuickCheck/Arbitrary/Generic.hs+9−4
@@ -32,6 +32,7 @@ The generated 'arbitrary' method is equivalent to
3232module Test.QuickCheck.Arbitrary.Generic
3333 ( GenericArbitrary(..)
3434 , Arbitrary(..)
35+ , Arg
3536 , genericArbitrary
3637 , genericShrink
3738 ) where
@@ -57,16 +58,20 @@ instance
5758 arbitrary = coerce (genericArbitrary :: Gen a)
5859 shrink = coerce (genericShrink :: a -> [a])
5960
61+type family TypesDiffer a b where
62+ TypesDiffer a a = 'False
63+ TypesDiffer a b = 'True
64+
65+type Arg self field = (TypesDiffer self field ~ 'True)
66+
6067type family AllFieldsFinal self (a :: * -> *) :: Bool where
6168 AllFieldsFinal self U1 = 'True
6269 AllFieldsFinal self (a :*: b) = AllFieldsFinal self a && AllFieldsFinal self b
63− AllFieldsFinal self (M1 S t (K1 R self)) = 'False
64− AllFieldsFinal self (M1 S t (K1 R other)) = 'True
70+ AllFieldsFinal self (M1 S t (K1 R field)) = TypesDiffer self field
6571
6672type family Finite self (a :: * -> *) :: Bool where
6773 Finite self U1 = 'True
68− Finite self (K1 R self) = 'False
69− Finite self (K1 R other) = 'True
74+ Finite self (K1 R field) = TypesDiffer self field
7075 Finite self (a :*: b) = Finite self a && Finite self b
7176 Finite self (M1 D t f) = Finite self f
7277 Finite self (a :+: b) = Finite self a || Finite self b
test/RecursiveTest.hs+12
@@ -106,3 +106,15 @@ instance Arbitrary DeepRecursive where
106106
107107prop_deepRecursiveTotal :: DeepRecursive -> Property
108108prop_deepRecursiveTotal = total
109+
110+data P p = NoP | P p
111+ deriving (Eq, Show, Generic)
112+
113+instance (NFData p) => NFData (P p)
114+
115+instance (Arg (P p) p, Arbitrary p) => Arbitrary (P p) where
116+ arbitrary = genericArbitrary
117+ shrink = genericShrink
118+
119+prop_Ptotal :: P (P Int) -> Property
120+prop_Ptotal = total