fitspec-0.2.0: bench/sorting.hs
import Data.List
import FitSpec
ordered :: Ord a => [a] -> Bool
ordered [] = True
ordered [_] = True
ordered (x:y:xs) = x <= y && ordered (y:xs)
permutation :: Eq a => [a] -> [a] -> Bool
[] `permutation` [] = True
(_:_) `permutation` [] = False
[] `permutation` (_:_) = False
(x:xs) `permutation` ys = x `elem` ys && xs `permutation` delete x ys
count :: Eq a => a -> [a] -> Int
count x = length . filter (==x)
properties :: (Ord a, Show a, Listable a)
=> ([a] -> [a]) -> [Property]
properties sort =
[ property $ \xs -> ordered (sort xs)
, property $ \xs -> length (sort xs) == length xs
, property $ \x xs -> elem x (sort xs) == elem x xs
, property $ \x xs -> count x (sort xs) == count x xs
, property $ \xs -> permutation xs (sort xs)
, property $ \x xs -> insert x (sort xs) == sort (x:xs)
]
sargs :: Args
sargs = args
{ names = ["sort xs"]
, timeout = 0
, nMutants = 1000
, nTests = 1000
}
--, extraMutants = take 0
-- . concat
-- . lsmap (. sort)
-- $ cons2 (\y ys -> (++ (y:ys))) -- prepend non-empty list
-- \++/ cons2 (\y ys -> ((y:ys) ++)) -- append non-empty list
type Ty a = [a] -> [a]
main :: IO ()
main = do
as <- getArgsWith sargs
let run f = reportWith as f properties
case concat $ extra as of
"bool" -> run (sort :: Ty Bool)
"bools" -> run (sort :: Ty [Bool])
"int" -> run (sort :: Ty Int)
"i1" -> run (sort :: Ty Int1)
"i2" -> run (sort :: Ty Int2)
"i3" -> run (sort :: Ty Int3)
"w1" -> run (sort :: Ty Word1)
"w2" -> run (sort :: Ty Word2)
"w3" -> run (sort :: Ty Word3)
"unit" -> run (sort :: Ty ())
"" -> run (sort :: Ty Word2)
t -> putStrLn $ "unknown type " ++ t
-- This hack is only necessary when using sortCounter as a manual mutant
instance Bounded a => Bounded [a] where
minBound = []
maxBound = repeat maxBound -- non terminating upper bound
sortCounter :: (Bounded a, Ord a) => [a] -> [a]
sortCounter = (++ [maxBound]) . sort