Created
May 5, 2012 11:09
-
-
Save joachifm/2601608 to your computer and use it in GitHub Desktop.
Volume values in the range 0-100
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Volume (runTest) where | |
import Control.Monad (forM_) | |
import qualified Test.QuickCheck as QC | |
-- | Volume values. | |
-- | |
-- Values of this type are always in the range 0-100. | |
-- | |
-- Arithmetic on volumes has the property that: | |
-- @current + new = 100 if current + new > 100@ | |
-- @current - new = 0 if current - new < 0@ | |
newtype Volume = Volume Int deriving (Eq, Ord, Show) | |
-- Smart constructor for volume values. | |
mkVolume :: Int -> Volume | |
mkVolume = Volume . f | |
where f x | x > 100 = 100 | |
| x < 0 = 0 | |
| otherwise = x | |
{-# INLINE mkVolume #-} | |
instance Enum Volume where | |
toEnum = mkVolume | |
fromEnum (Volume x) = x | |
instance Num Volume where | |
Volume x + Volume y = mkVolume (x + y) | |
Volume x - Volume y = mkVolume (x - y) | |
Volume x * Volume y = mkVolume (x * y) | |
negate = id | |
abs = id | |
signum = const 1 | |
fromInteger = mkVolume . fromIntegral | |
instance QC.Arbitrary Volume where | |
arbitrary = QC.elements [0..100] | |
inRange :: Ord a => a -> a -> a -> Bool | |
inRange l h x = l <= x && x <= h | |
prop_volume_arith op cur new = inRange 0 100 (cur `op` new) | |
where cur' = cur :: Volume | |
prop_volume_add = prop_volume_arith (+) | |
prop_volume_sub = prop_volume_arith (-) | |
prop_volume_mul = prop_volume_arith (*) | |
runTest = forM_ tests $ (\(n, f) -> putStr (n ++ ": ") >> f) | |
where | |
tests = [ ("prop / volume add", QC.quickCheck prop_volume_add) | |
, ("prop / volume sub", QC.quickCheck prop_volume_sub) | |
, ("prop / volume mul", QC.quickCheck prop_volume_mul) | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment