{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -Wall #-}
module Test.QuickCheck.Classes.Ix
( ixLaws
) where
import Data.Ix (Ix(..))
import Data.Proxy (Proxy)
import Test.QuickCheck hiding ((.&.))
import Test.QuickCheck.Property (Property)
import Test.QuickCheck.Classes.Internal (Laws(..))
-- | Tests the various 'Ix' properties:
--
-- @'inRange' (l,u) i '==' 'elem' i ('range' (l,u))@
--
-- @'range' (l,u) '!!' 'index' (l,u) i '==' i@, when @'inRange' (l,u) i@
--
-- @'map' ('index' (l,u)) ('range' (l,u)) '==' [0 .. 'rangeSize' (l,u) - 1]@
--
-- @'rangeSize' (l,u) '==' 'length' ('range' (l,u))@
ixLaws :: (Ix a, Arbitrary a, Show a) => Proxy a -> Laws
ixLaws p = Laws "Ix"
[ ("InRange", ixInRange p)
, ("RangeIndex", ixRangeIndex p)
, ("MapIndexRange", ixMapIndexRange p)
, ("RangeSize", ixRangeSize p)
]
ixInRange :: forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
ixInRange _ = property $ \(l :: a) (u :: a) (i :: a) -> (l <= u) ==> do
inRange (l,u) i == elem i (range (l,u))
ixRangeIndex :: forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
ixRangeIndex _ = property $ \(l :: a) (u :: a) (i :: a) -> ((l <= u) && (i >= l && i <= u)) ==> do
range (l,u) !! index (l,u) i == i
ixMapIndexRange :: forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
ixMapIndexRange _ = property $ \(l :: a) (u :: a) -> (l <= u) ==> do
map (index (l,u)) (range (l,u)) == [0 .. rangeSize (l,u) - 1]
ixRangeSize :: forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
ixRangeSize _ = property $ \(l :: a) (u :: a) -> (l <= u) ==> do
rangeSize (l,u) == length (range (l,u))