{-# language ConstraintKinds #-}
{-# language FlexibleInstances #-}
{-# language GADTs #-}
{-# language MultiParamTypeClasses #-}
{-# language StandaloneDeriving #-}
{-# language TemplateHaskell #-}
{-# language TypeFamilies #-}
module Main where
import Control.Monad
import Control.Monad.Identity
import Data.Maybe
import Data.Constraint.Extras.TH
import Data.GADT.Compare
import Data.GADT.Show
import Data.Hashable
import Hedgehog
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import Data.Dependent.HashMap (DHashMap, DSum((:=>)), Some(Some))
import qualified Data.Dependent.HashMap as DHashMap
data Key v where
IntKey :: Int -> Key Int
StringKey :: String -> Key String
deriving instance Show (Key v)
instance GShow Key where
gshowsPrec = showsPrec
instance Hashable (Some Key) where
hashWithSalt salt (Some key) =
case key of
IntKey i -> hashWithSalt salt i `mod` 20
StringKey s -> hashWithSalt salt s `mod` 20
instance GRead Key where
greadsPrec d s =
readParen (d > 10)
(\s' ->
[ (GReadResult $ \f -> f $ IntKey i, s''')
| ("IntKey", s'') <- lex s'
, (i, s''') <- readsPrec (10+1) s''
]
)
s
++
readParen (d > 10)
(\s' ->
[ (GReadResult $ \f -> f $ StringKey m, s''')
| ("StringKey", s'') <- lex s'
, (m, s''') <- readsPrec (10+1) s''
]
)
s
deriveArgDict ''Key
instance GEq Key where
geq (IntKey i1) (IntKey i2)
| i1 == i2 =
Just Refl
geq (StringKey s1) (StringKey s2)
| s1 == s2 =
Just Refl
geq _ _ =
Nothing
int :: Gen Int
int = Gen.int (Range.linear 0 100)
string :: Gen String
string = Gen.string (Range.linear 0 100) Gen.ascii
-- key :: Gen (Some Key)
-- key =
-- Gen.choice
-- [ Some . IntKey <$> int
-- , Some . StringKey <$> string
-- ]
dSum :: Gen (DHashMap.DSum Key Identity)
dSum =
Gen.choice
[ (:=>) <$> (IntKey <$> int) <*> (Identity <$> int)
, (:=>) <$> (StringKey <$> string) <*> (Identity <$> string)
]
dHashMap :: Gen (DHashMap Key Identity)
dHashMap =
DHashMap.fromList <$> Gen.list (Range.linear 0 100) dSum
prop_show_read :: Property
prop_show_read =
property $ do
m <- forAll dHashMap
m === read (show m)
prop_empty :: Property
prop_empty =
property $ do
i <- forAll int
DHashMap.lookup (IntKey i) (mempty :: DHashMap Key Identity) === Nothing
s <- forAll string
DHashMap.lookup (StringKey s) (mempty :: DHashMap Key Identity) === Nothing
prop_singleton :: Property
prop_singleton =
property $ do
i <- forAll int
j <- forAll int
DHashMap.lookup (IntKey i) (DHashMap.singleton (IntKey i) (Identity j)) === Just (Identity j)
s <- forAll string
DHashMap.lookup (StringKey s) (DHashMap.singleton (IntKey i) (Identity j)) === Nothing
prop_null_size :: Property
prop_null_size =
property $ do
h <- forAll dHashMap
DHashMap.null h === (DHashMap.size h == 0)
prop_member_lookup :: Property
prop_member_lookup =
property $ do
h <- forAll dHashMap
i <- forAll int
isJust (DHashMap.lookup (IntKey i) h) === DHashMap.member (IntKey i) h
s <- forAll string
isJust (DHashMap.lookup (StringKey s) h) === DHashMap.member (StringKey s) h
prop_insert_lookup :: Property
prop_insert_lookup =
property $ do
h <- forAll dHashMap
i <- forAll int
j <- forAll int
DHashMap.lookup (IntKey i) (DHashMap.insert (IntKey i) (Identity j) h) === Just (Identity j)
s <- forAll string
t <- forAll string
DHashMap.lookup (StringKey s) (DHashMap.insert (StringKey s) (Identity t) h) === Just (Identity t)
prop_bang_lookup :: Property
prop_bang_lookup =
property $ do
h <- forAll dHashMap
i <- forAll int
j <- forAll int
DHashMap.insert (IntKey i) (Identity j) h DHashMap.! IntKey i === Identity j
s <- forAll string
t <- forAll string
DHashMap.insert (StringKey s) (Identity t) h DHashMap.! StringKey s === Identity t
prop_lookup_default :: Property
prop_lookup_default =
property $ do
h <- forAll dHashMap
i <- forAll int
j <- forAll int
DHashMap.lookupDefault (Identity j) (IntKey i) h ===
if DHashMap.member (IntKey i) h then
h DHashMap.! IntKey i
else
Identity j
prop_lookup_delete :: Property
prop_lookup_delete =
property $ do
h <- forAll dHashMap
i <- forAll int
DHashMap.lookup (IntKey i) (DHashMap.delete (IntKey i) h) === Nothing
main :: IO ()
main =
void $ checkParallel $$(discover)