11{-# LANGUAGE CPP #-}
22
3- -- CPP: GHC >= 7.8 for Safe Haskell
4- #if __GLASGOW_HASKELL__ >= 708
3+ #if MIN_VERSION_base(4,9,0)
54{-# LANGUAGE Safe #-}
6- #endif
7-
5+ {-# LANGUAGE TypeApplications #-}
6+ {-# LANGUAGE FlexibleContexts #-}
7+ {-# LANGUAGE DeriveFunctor #-}
88--------------------------------------------------------------------------------
99
1010-- | QuickCheck property tests for DNonEmpty.
@@ -22,11 +22,16 @@ import QuickCheckUtil
2222import Test.QuickCheck
2323import Text.Show.Functions ()
2424import Prelude hiding (head , map , tail )
25+ import Data.Monoid (Sum )
26+
27+ -- NonEmpty.append was only added in base 4.16
28+ nonEmptyAppend :: NonEmpty a -> NonEmpty a -> NonEmpty a
29+ nonEmptyAppend (x NonEmpty. :| xs) ys = x NonEmpty. :| (xs ++ NonEmpty. toList ys)
2530
2631--------------------------------------------------------------------------------
2732
28- prop_model :: NonEmpty Int -> Bool
29- prop_model = eqWith id (toNonEmpty . fromNonEmpty)
33+ prop_model :: DNonEmpty Int -> Bool
34+ prop_model = eqWith id id
3035
3136prop_singleton :: Int -> Bool
3237prop_singleton = eqWith Applicative. pure (toNonEmpty . singleton)
@@ -36,18 +41,30 @@ prop_cons c = eqWith (NonEmpty.cons c) (toNonEmpty . cons c . fromNonEmpty)
3641
3742prop_snoc :: NonEmpty Int -> Int -> Bool
3843prop_snoc xs c =
39- xs Semigroup. <> Applicative. pure c == toNonEmpty (snoc (fromNonEmpty xs) c)
44+ xs `nonEmptyAppend` Applicative. pure c == toNonEmpty (snoc (fromNonEmpty xs) c)
4045
4146prop_append :: NonEmpty Int -> NonEmpty Int -> Bool
4247prop_append xs ys =
43- xs Semigroup. <> ys == toNonEmpty (fromNonEmpty xs `append` fromNonEmpty ys)
48+ xs `nonEmptyAppend` ys == toNonEmpty (fromNonEmpty xs `append` fromNonEmpty ys)
4449
4550prop_head :: NonEmpty Int -> Bool
4651prop_head = eqWith NonEmpty. head (head . fromNonEmpty)
4752
4853prop_tail :: NonEmpty Int -> Bool
4954prop_tail = eqWith NonEmpty. tail (DList. toList . tail . fromNonEmpty)
5055
56+ prop_foldr :: Eq b => (a -> b -> b ) -> b -> NonEmpty a -> Bool
57+ prop_foldr f initial l = foldr f initial l == foldr f initial (fromNonEmpty l)
58+
59+ prop_foldr1 :: Eq a => (a -> a -> a ) -> NonEmpty a -> Bool
60+ prop_foldr1 f l = foldr1 f l == foldr1 f (fromNonEmpty l)
61+
62+ prop_foldl :: Eq b => (b -> a -> b ) -> b -> NonEmpty a -> Bool
63+ prop_foldl f initial l = foldl f initial l == foldl f initial (fromNonEmpty l)
64+
65+ prop_foldMap :: (Eq b , Monoid b ) => (a -> b ) -> NonEmpty a -> Bool
66+ prop_foldMap f l = foldMap f l == foldMap f (fromNonEmpty l)
67+
5168prop_unfoldr :: (Int -> (Int , Maybe Int )) -> Int -> Int -> Property
5269prop_unfoldr f n =
5370 eqOn
@@ -59,7 +76,15 @@ prop_map :: (Int -> Int) -> NonEmpty Int -> Bool
5976prop_map f = eqWith (NonEmpty. map f) (toNonEmpty . map f . fromNonEmpty)
6077
6178prop_show_read :: NonEmpty Int -> Bool
62- prop_show_read = eqWith id (read . show )
79+ prop_show_read = eqWith id (read . show ) . fromNonEmpty
80+
81+ prop_inner_show_read ::
82+ ( Eq (f (DNonEmpty a ))
83+ , Show (f (DNonEmpty a ))
84+ , Read (f (DNonEmpty a ))
85+ , Functor f
86+ ) => f (NonEmpty a ) -> Bool
87+ prop_inner_show_read = eqWith id (read . show ) . fmap fromNonEmpty
6388
6489prop_read_show :: NonEmpty Int -> Bool
6590prop_read_show x = eqWith id (show . f . read ) $ " fromNonEmpty (" ++ show x ++ " )"
@@ -87,6 +112,21 @@ prop_Semigroup_append xs ys =
87112
88113--------------------------------------------------------------------------------
89114
115+ newtype Single a = Single a
116+ deriving (Eq , Read , Show , Functor )
117+
118+ instance Arbitrary a => Arbitrary (Single a ) where
119+ arbitrary = Single <$> arbitrary
120+
121+ instance Arbitrary a => Arbitrary (DList. DList a ) where
122+ arbitrary = DList. fromList <$> arbitrary
123+
124+ instance Arbitrary a => Arbitrary (DNonEmpty a ) where
125+ arbitrary = do
126+ x <- arbitrary
127+ xs <- arbitrary
128+ pure $ x :| xs
129+
90130properties :: [(String , Property )]
91131properties =
92132 [ (" model" , property prop_model),
@@ -97,10 +137,30 @@ properties =
97137 (" head" , property prop_head),
98138 (" tail" , property prop_tail),
99139 (" unfoldr" , property prop_unfoldr),
140+ (" foldr" , property (prop_foldr @ Int @ Int )),
141+ (" foldr1" , property (prop_foldr1 @ Int )),
142+ (" foldl" , property (prop_foldl @ Int @ Int )),
143+ (" foldMap" , property (prop_foldMap @ (Sum Int ) @ Int )),
100144 (" map" , property prop_map),
101145 (" read . show" , property prop_show_read),
146+ (" read . show" , property (prop_inner_show_read @ Single @ Int )),
147+ (" read . show" , property (prop_inner_show_read @ ((,) Int ) @ (Int , Int ))),
148+ (" read . show" , property (prop_inner_show_read @ Single @ (DNonEmpty Int ))),
102149 (" show . read" , property prop_read_show),
103150 (" toList" , property prop_toList),
104151 (" fromList" , property prop_fromList),
105152 (" Semigroup <>" , property prop_Semigroup_append)
106153 ]
154+
155+ #else
156+
157+ #warning Skipping DNonEmptyProperties tests due to old version of base
158+
159+ module DNonEmptyProperties (properties ) where
160+
161+ import Test.QuickCheck
162+
163+ properties :: [(String , Property )]
164+ properties = []
165+
166+ #endif
0 commit comments