Skip to content

Instantly share code, notes, and snippets.

@joachifm
Created May 5, 2012 11:09
Show Gist options
  • Save joachifm/2601608 to your computer and use it in GitHub Desktop.
Save joachifm/2601608 to your computer and use it in GitHub Desktop.
Volume values in the range 0-100
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