{-# LANGUAGE TemplateHaskell #-} module Test.Data.Group.Free ( tests ) where import Control.Monad (mapM) import Data.Semigroup (Semigroup (..)) import Data.Group (invert) import Data.DList (DList) import qualified Data.DList as DList import Hedgehog (Property, Gen, property, (===)) import qualified Hedgehog as H import qualified Hedgehog.Gen as Gen import qualified Hedgehog.Range as Range import Data.Group.Free (fromDList, normalize) genDList :: Gen a -> Gen (DList (Either a a)) genDList gen = do as <- Gen.list (Range.linear 0 100) gen DList.fromList <$> mapM (\a -> do b <- Gen.bool if b then return $ Right a else return $ Left a ) as prop_normalize :: Property prop_normalize = property $ do as <- H.forAll (genDList Gen.bool) normalize (normalize as) === normalize as normalize (as `DList.append` rev as) === DList.empty where rev :: DList (Either a a) -> DList (Either a a) rev = DList.foldr (\a as -> DList.snoc as (either Right Left a)) DList.empty prop_invert :: Property prop_invert = property $ do fg <- fromDList <$> H.forAll (genDList Gen.bool) invert (invert fg) === fg invert fg <> fg === mempty fg <> invert fg === mempty prop_unit :: Property prop_unit = property $ do fg <- fromDList <$> H.forAll (genDList Gen.bool) fg <> mempty === fg mempty <> fg === fg prop_associativity :: Property prop_associativity = property $ do fg <- fromDList <$> H.forAll (genDList Gen.bool) fg' <- fromDList <$> H.forAll (genDList Gen.bool) fg'' <- fromDList <$> H.forAll (genDList Gen.bool) (fg <> fg') <> fg'' === fg <> (fg' <> fg'') tests :: IO Bool tests = H.checkParallel $$(H.discover)