{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Applicative
import Control.Monad
import Data.Either.Validation
import Data.Functor (void)
import Data.Monoid (Sum(..))
import System.Exit (exitFailure)
import Hedgehog
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import Hedgehog.Checkers
genValidation :: Gen a -> Gen b -> Gen (Validation a b)
genValidation ga gb = do
a <- ga
b <- gb
Gen.choice [return $ Failure a, return $ Success b]
validationAlternative :: Property
validationAlternative = property $ do
let genSumInt = Sum <$> Gen.int (Range.linear 0 maxBound)
genVal = genValidation genSumInt genSumInt
alternative genVal
genInt :: Gen Int
genInt = Gen.int (Range.linear 0 maxBound)
genSum :: Gen (Sum Int)
genSum = Sum <$> genInt
genEither' :: Gen a -> Gen b -> Gen (Either a b)
genEither' ga gb = do
a <- ga
b <- gb
Gen.choice [return $ Left a, return $ Right b]
genEither :: Gen (Either Int Int)
genEither = genEither' genInt genInt
eitherAlt :: Property
eitherAlt = property $ do
alt genEither
eitherBifunctor :: Property
eitherBifunctor = property $ do
bifunctor genEither genInt genInt genInt
eitherFunctor :: Property
eitherFunctor = property $ do
functor genEither
eitherApply :: Property
eitherApply = property $ do
apply genEither genInt genInt genInt
eitherApplicative :: Property
eitherApplicative = property $ do
applicative genEither genInt genInt genInt
eitherSemigroup :: Property
eitherSemigroup = property $ do
semigroup genEither
genMaybe' :: Gen a -> Gen (Maybe a)
genMaybe' ga =
-- I need to bias this to Just
Gen.choice [return Nothing, Just <$> ga]
genMaybe :: Gen (Maybe (Sum Int))
genMaybe = genMaybe' genSum
maybeMonoid :: Property
maybeMonoid = property $ do
monoid genMaybe
maybeAlt :: Property
maybeAlt = property $ alt genMaybe
maybeAlternative :: Property
maybeAlternative = property $ alternative genMaybe
maybeAlternativeAlt :: Property
maybeAlternativeAlt = property $ alternativeAltAgreement genMaybe
maybeApply :: Property
maybeApply = property $
apply genMaybe genSum genSum genSum
maybeApplicative :: Property
maybeApplicative = property $
applicative genMaybe genSum genSum genSum
maybeApplicativeApply :: Property
maybeApplicativeApply = property $
applicativeApplyAgreement genMaybe genSum genSum
intOrd :: Property
intOrd = property $
ord genInt varyGenInt
where varyGenInt i =
Gen.int (Range.linear i maxBound)
main :: IO ()
main = do
e <-
checkParallel $
Group "Data.Either" [ ("Alt", eitherAlt)
, ("Bifunctor", eitherBifunctor)
, ("Functor", eitherFunctor)
, ("Semigroup", eitherSemigroup)
, ("Apply", eitherApply)
, ("Applicative", eitherApplicative)
]
m <-
checkParallel $
Group "Data.Maybe" [ ("Monoid", maybeMonoid)
, ("Alt", maybeAlt)
, ("Alternative", maybeAlternative)
, ("AlternativeAlt", maybeAlternativeAlt)
, ("Apply", maybeApply)
, ("Applicative", maybeApplicative)
, ("ApplicativeApply", maybeApplicativeApply)
]
o <-
checkParallel $
Group "Ord" [ ("Int", intOrd)
]
unless (and [e,m,o]) exitFailure