{-# LANGUAGE KindSignatures #-}
module Main (main) where
import Prelude hiding (Either(..), either)
import Control.Applicative
import Control.Monad (liftM)
import Data.Functor.Classes
import Data.Either.Unpacked (Either(Left,Right), left, right)
import Data.Proxy (Proxy(..))
import Data.Semigroup (Semigroup((<>)))
import Test.QuickCheck.Classes
import Test.QuickCheck.Arbitrary
import Test.QuickCheck.Gen
main :: IO ()
main = lawsCheckMany myClassTests
myClassTests :: [(String, [Laws])]
myClassTests =
[ ("Ground types", myLaws eitherProxy)
, ("Higher-kinded types", myLaws1 eitherProxy1)
]
myLaws
:: (Arbitrary a, Eq a, Ord a, Show a, Read a)
=> Proxy a -> [Laws]
myLaws p =
[ eqLaws p
, ordLaws p
, showReadLaws p
]
myLaws1
:: (Arbitrary1 a, Monad a, Functor a, Applicative a, Foldable a, Traversable a, Eq1 a, Show1 a)
=> Proxy a -> [Laws]
myLaws1 p =
[ monadLaws p
, functorLaws p
, applicativeLaws p
, foldableLaws p
, traversableLaws p
]
eitherProxy2 :: Proxy Either
eitherProxy2 = Proxy
eitherProxy1 :: Proxy (Either Int)
eitherProxy1 = Proxy
eitherProxy :: Proxy (Either Int Int)
eitherProxy = Proxy
instance Semigroup Int where
(<>) = (+)
instance Monoid Int where
mempty = 0
mappend = (+)
instance (Arbitrary a, Arbitrary b) => Arbitrary (Either a b) where
arbitrary = arbitrary2
shrink = shrink2
instance Arbitrary2 Either where
liftArbitrary2 arbA arbB = oneof [liftM Left arbA, liftM Right arbB]
liftShrink2 shrA _ (Left x) = [ Left x' | x' <- shrA x ]
liftShrink2 _ shrB (Right y) = [ Right y' | y' <- shrB y ]
instance Arbitrary a => Arbitrary1 (Either a) where
liftArbitrary = liftArbitrary2 arbitrary
liftShrink = liftShrink2 shrink