11{-# LANGUAGE CPP #-}
22
3- -- CPP: GHC >= 7.8 for Safe Haskell
4- #if __GLASGOW_HASKELL__ >= 708
5- {-# LANGUAGE Safe #-}
6- #endif
7-
3+ #if MIN_VERSION_base(4,9,0)
4+ {-# LANGUAGE DeriveFunctor #-}
5+ {-# LANGUAGE FlexibleContexts #-}
6+ {-# LANGUAGE Safe #-}
7+ {-# LANGUAGE TypeApplications #-}
8+ {-# OPTIONS_GHC -Wno-orphans #-}
89--------------------------------------------------------------------------------
910
1011-- | QuickCheck property tests for DNonEmpty.
@@ -22,11 +23,16 @@ import QuickCheckUtil
2223import Test.QuickCheck
2324import Text.Show.Functions ()
2425import Prelude hiding (head , map , tail )
26+ import Data.Monoid (Sum )
27+
28+ -- NonEmpty.append was only added in base 4.16
29+ nonEmptyAppend :: NonEmpty a -> NonEmpty a -> NonEmpty a
30+ nonEmptyAppend (x NonEmpty. :| xs) ys = x NonEmpty. :| (xs ++ NonEmpty. toList ys)
2531
2632--------------------------------------------------------------------------------
2733
28- prop_model :: NonEmpty Int -> Bool
29- prop_model = eqWith id (toNonEmpty . fromNonEmpty)
34+ prop_model :: DNonEmpty Int -> Bool
35+ prop_model = eqWith id id
3036
3137prop_singleton :: Int -> Bool
3238prop_singleton = eqWith Applicative. pure (toNonEmpty . singleton)
@@ -36,18 +42,30 @@ prop_cons c = eqWith (NonEmpty.cons c) (toNonEmpty . cons c . fromNonEmpty)
3642
3743prop_snoc :: NonEmpty Int -> Int -> Bool
3844prop_snoc xs c =
39- xs Semigroup. <> Applicative. pure c == toNonEmpty (snoc (fromNonEmpty xs) c)
45+ xs `nonEmptyAppend` Applicative. pure c == toNonEmpty (snoc (fromNonEmpty xs) c)
4046
4147prop_append :: NonEmpty Int -> NonEmpty Int -> Bool
4248prop_append xs ys =
43- xs Semigroup. <> ys == toNonEmpty (fromNonEmpty xs `append` fromNonEmpty ys)
49+ xs `nonEmptyAppend` ys == toNonEmpty (fromNonEmpty xs `append` fromNonEmpty ys)
4450
4551prop_head :: NonEmpty Int -> Bool
4652prop_head = eqWith NonEmpty. head (head . fromNonEmpty)
4753
4854prop_tail :: NonEmpty Int -> Bool
4955prop_tail = eqWith NonEmpty. tail (DList. toList . tail . fromNonEmpty)
5056
57+ prop_foldr :: Eq b => (a -> b -> b ) -> b -> NonEmpty a -> Bool
58+ prop_foldr f initial l = foldr f initial l == foldr f initial (fromNonEmpty l)
59+
60+ prop_foldr1 :: Eq a => (a -> a -> a ) -> NonEmpty a -> Bool
61+ prop_foldr1 f l = foldr1 f l == foldr1 f (fromNonEmpty l)
62+
63+ prop_foldl :: Eq b => (b -> a -> b ) -> b -> NonEmpty a -> Bool
64+ prop_foldl f initial l = foldl f initial l == foldl f initial (fromNonEmpty l)
65+
66+ prop_foldMap :: (Eq b , Monoid b ) => (a -> b ) -> NonEmpty a -> Bool
67+ prop_foldMap f l = foldMap f l == foldMap f (fromNonEmpty l)
68+
5169prop_unfoldr :: (Int -> (Int , Maybe Int )) -> Int -> Int -> Property
5270prop_unfoldr f n =
5371 eqOn
@@ -61,6 +79,14 @@ prop_map f = eqWith (NonEmpty.map f) (toNonEmpty . map f . fromNonEmpty)
6179prop_show_read :: NonEmpty Int -> Bool
6280prop_show_read = eqWith id (read . show ) . fromNonEmpty
6381
82+ prop_inner_show_read ::
83+ ( Eq (f (DNonEmpty a ))
84+ , Show (f (DNonEmpty a ))
85+ , Read (f (DNonEmpty a ))
86+ , Functor f
87+ ) => f (NonEmpty a ) -> Bool
88+ prop_inner_show_read = eqWith id (read . show ) . fmap fromNonEmpty
89+
6490prop_read_show :: NonEmpty Int -> Bool
6591prop_read_show x = eqWith id (show . f . read ) $ " fromNonEmpty (" ++ show x ++ " )"
6692 where
@@ -87,6 +113,21 @@ prop_Semigroup_append xs ys =
87113
88114--------------------------------------------------------------------------------
89115
116+ newtype Single a = Single a
117+ deriving (Eq , Read , Show , Functor )
118+
119+ instance Arbitrary a => Arbitrary (Single a ) where
120+ arbitrary = Single <$> arbitrary
121+
122+ instance Arbitrary a => Arbitrary (DList. DList a ) where
123+ arbitrary = DList. fromList <$> arbitrary
124+
125+ instance Arbitrary a => Arbitrary (DNonEmpty a ) where
126+ arbitrary = do
127+ x <- arbitrary
128+ xs <- arbitrary
129+ pure $ x :| xs
130+
90131properties :: [(String , Property )]
91132properties =
92133 [ (" model" , property prop_model),
@@ -97,10 +138,30 @@ properties =
97138 (" head" , property prop_head),
98139 (" tail" , property prop_tail),
99140 (" unfoldr" , property prop_unfoldr),
141+ (" foldr" , property (prop_foldr @ Int @ Int )),
142+ (" foldr1" , property (prop_foldr1 @ Int )),
143+ (" foldl" , property (prop_foldl @ Int @ Int )),
144+ (" foldMap" , property (prop_foldMap @ (Sum Int ) @ Int )),
100145 (" map" , property prop_map),
101146 (" read . show" , property prop_show_read),
147+ (" read . show" , property (prop_inner_show_read @ Single @ Int )),
148+ (" read . show" , property (prop_inner_show_read @ ((,) Int ) @ (Int , Int ))),
149+ (" read . show" , property (prop_inner_show_read @ Single @ (DNonEmpty Int ))),
102150 (" show . read" , property prop_read_show),
103151 (" toList" , property prop_toList),
104152 (" fromList" , property prop_fromList),
105153 (" Semigroup <>" , property prop_Semigroup_append)
106154 ]
155+
156+ #else
157+
158+ #warning Skipping DNonEmptyProperties tests due to old version of base
159+
160+ module DNonEmptyProperties (properties ) where
161+
162+ import Test.QuickCheck
163+
164+ properties :: [(String , Property )]
165+ properties = []
166+
167+ #endif
0 commit comments