{-# LANGUAGE KindSignatures #-}
module Main (main) where
import Prelude hiding (Maybe(..), maybe)
import Control.Applicative
import Control.Monad (liftM, MonadPlus)
import Control.Monad.Zip (MonadZip)
import Data.Functor.Classes
import Data.Maybe.Unpacked (Maybe(Just, Nothing), nothing, just)
import Data.Monoid (Monoid(mempty,mappend))
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 maybeInt)
, ("Higher-kinded types", myLaws1 maybeProxy)
]
myLaws
:: (Arbitrary a, Monoid a, Eq a, Ord a, Semigroup a, Show a, Read a)
=> Proxy a -> [Laws]
myLaws p =
[ commutativeMonoidLaws p
, eqLaws p
, ordLaws p
, semigroupLaws p
, showReadLaws p
]
myLaws1
:: (Arbitrary1 a, Alternative a, Applicative a, Foldable a, Functor a, Monad a, MonadPlus a, MonadZip a, Traversable a, Eq1 a, Show1 a)
=> Proxy a -> [Laws]
myLaws1 p =
[ alternativeLaws p
, applicativeLaws p
, foldableLaws p
, functorLaws p
, monadLaws p
, monadPlusLaws p
, monadZipLaws p
, traversableLaws p
]
maybeProxy :: Proxy Maybe
maybeProxy = Proxy
maybeInt :: Proxy (Maybe Int)
maybeInt = Proxy
instance Semigroup Int where
(<>) = (+)
instance Monoid Int where
mempty = 0
mappend = (+)
instance Arbitrary a => Arbitrary (Maybe a) where
arbitrary = arbitrary1
shrink = shrink1
instance Arbitrary1 Maybe where
liftArbitrary arb = frequency [(1, return nothing), (3, liftM just arb)]
liftShrink shr (Just x) = nothing : [ just x' | x' <- shr x ]
liftShrink _ Nothing = []