-- | Gives instance of the class Arbitrary for several data types of the
-- library. These instances are needed by QuickCheck.
-- See also "Tests".
module Arbitraries where
import Control.Monad
import Data.Generics (Typeable, Data)
import Test.QuickCheck
import Language.Haskell.FreeTheorems.Syntax
import Language.Haskell.FreeTheorems.LanguageSubsets
newtype ListOfDeclarations = ListOfDeclarations
{ getDeclarations :: [Declaration] }
deriving (Eq, Show)
instance Arbitrary ListOfDeclarations where
arbitrary = do n <- choose (1, 100)
liftM ListOfDeclarations (replicateM n arbitrary)
coarbitrary _ = id
instance Arbitrary Declaration where
arbitrary = oneof [ liftM DataDecl arbitrary
, liftM NewtypeDecl arbitrary
, liftM TypeDecl arbitrary
, liftM ClassDecl arbitrary
, liftM TypeSig arbitrary ]
coarbitrary _ = id
instance Arbitrary DataDeclaration where
arbitrary = do n <- arbIdent id 'T'
[ "Bool", "Maybe", "Either", "Ordering" ]
v <- choose (0, 5)
c <- choose (1, 7)
liftM2 (Data n) (replicateM v arbitrary)
(replicateM c arbitrary)
coarbitrary _ = id
instance Arbitrary NewtypeDeclaration where
arbitrary = do n <- arbIdent id 'T' []
v <- choose (0, 5)
c <- arbIdent id 'D' []
liftM2 (\vs -> Newtype n vs c)
(replicateM v arbitrary) arbitrary
coarbitrary _ = id
instance Arbitrary TypeDeclaration where
arbitrary = do n <- arbIdent id 'T'
[ "String", "Ordering", "Rational", "ShowS", "ReadS"
, "FilePath" ]
v <- choose (0, 5)
liftM2 (Type n) (replicateM v arbitrary) arbitrary
coarbitrary _ = id
instance Arbitrary ClassDeclaration where
arbitrary = do c <- choose (0, 3)
p <- replicateM c (arbitrary :: Gen TypeClass)
n <- arbIdent id 'C'
[ "Eq", "Ord", "Num", "Integral", "Show", "Read"
, "Bounded", "Enum", "Real", "Fractional", "Floating"
, "RealFrac", "RealFloat" ]
s <- choose (0, 10)
liftM2 (Class p n) arbitrary (replicateM s arbitrary)
coarbitrary _ = id
instance Arbitrary Signature where
arbitrary = do s <- arbIdent id 'f'
[ "not", "(&&)", "(||)", "(==)", "(/=)", "maybe"
, "either", "fst", "snd", "curry", "uncurry", "(<)"
, "(>)", "max", "min", "succ", "pred", "(+)", "(-)"
, "div", "mod", "pi", "id", "flip", "const", "map"
, "filter", "head", "tail", "length", "foldr", "foldl" ]
liftM (Signature s) arbitrary
coarbitrary _ = id
instance Arbitrary DataConstructorDeclaration where
arbitrary = do con <- arbIdent id 'D'
[ "False", "True", "Left", "Right", "Nothing"
, "Just", "LT", "GT", "EQ" ]
i <- choose (0, 5)
liftM (DataCon con) (replicateM i arbitrary)
coarbitrary _ = id
instance Arbitrary BangTypeExpression where
arbitrary = oneof [ liftM Banged arbitrary, liftM Unbanged arbitrary ]
coarbitrary _ = id
instance Arbitrary TypeExpression where
arbitrary = sized arbTypeExpr
coarbitrary _ = id
arbTypeExpr n =
if n == 0
then oneof [ liftM TypeVar arbitrary
, liftM (\c -> TypeCon c []) arbitrary
, liftM TypeExp arbitrary ]
else frequency [ (1, arbTypeExpr 0)
, (2, arbComplexTypeExpr (n `div` 2))
]
arbComplexTypeExpr n = oneof
[ do r <- choose (1, 7)
liftM2 TypeCon arbitrary (replicateM r (arbTypeExpr n))
, liftM2 TypeFun (arbTypeExpr n) (arbTypeExpr n)
, do c <- choose (0, 2)
liftM3 TypeAbs arbitrary (replicateM c arbitrary) (arbTypeExpr n)
]
instance Arbitrary TypeConstructor where
arbitrary = oneof
[ oneof
[ return ConUnit
, return ConList
, do n <- choose (2, 15)
return (ConTuple n)
, return ConInt
, return ConInteger
, return ConFloat
, return ConDouble
, return ConChar
]
, arbIdent Con 'T'
[ "Bool", "Maybe", "Either", "String", "Ordering"
, "Rational", "ShowS", "ReadS", "FilePath" ]
]
coarbitrary _ = id
instance Arbitrary TypeVariable where
arbitrary = arbIdent TV 'a' ["a", "b", "c", "d", "e"]
coarbitrary _ = id
instance Arbitrary TypeClass where
arbitrary = arbIdent TC 'C'
[ "Eq", "Ord", "Num", "Integral", "Show", "Read", "Bounded"
, "Enum", "Real", "Fractional", "Floating", "RealFrac"
, "RealFloat" ]
coarbitrary _ = id
instance Arbitrary FixedTypeExpression where
arbitrary = oneof (map (return . TF . Ident) [ "t1", "t2", "t3", "t4", "t5" ])
coarbitrary _ = id
instance Arbitrary LanguageSubset where
arbitrary = oneof
[ return $ BasicSubset
, return $ SubsetWithFix EquationalTheorem
, return $ SubsetWithFix InequationalTheorem
, return $ SubsetWithSeq EquationalTheorem
, return $ SubsetWithSeq InequationalTheorem
]
coarbitrary _ = id
arbIdent :: (Identifier -> a) -> Char -> [String] -> Gen a
arbIdent f c xs =
oneof . map (return . f . Ident) $ xs ++ map (\i -> c : show i) [1..20]