module Main (main) where import qualified Data.PQueue.Prio.Max as PMax () import qualified Data.PQueue.Prio.Min as PMin () import qualified Data.PQueue.Max as Max () import qualified Data.PQueue.Min as Min import Test.QuickCheck import System.Exit import qualified Data.List as List import Control.Arrow (second) validMinToAscList :: [Int] -> Bool validMinToAscList xs = Min.toAscList (Min.fromList xs) == List.sort xs validMinToDescList :: [Int] -> Bool validMinToDescList xs = Min.toDescList (Min.fromList xs) == List.sortBy (flip compare) xs validMinUnfoldr :: [Int] -> Bool validMinUnfoldr xs = List.unfoldr Min.minView (Min.fromList xs) == List.sort xs validMinToList :: [Int] -> Bool validMinToList xs = List.sort (Min.toList (Min.fromList xs)) == List.sort xs validMinFromAscList :: [Int] -> Bool validMinFromAscList xs = Min.fromAscList (List.sort xs) == Min.fromList xs validMinFromDescList :: [Int] -> Bool validMinFromDescList xs = Min.fromDescList (List.sortBy (flip compare) xs) == Min.fromList xs validMinUnion :: [Int] -> [Int] -> Bool validMinUnion xs1 xs2 = Min.union (Min.fromList xs1) (Min.fromList xs2) == Min.fromList (xs1 ++ xs2) validMinMapMonotonic :: [Int] -> Bool validMinMapMonotonic xs = Min.mapU (+1) (Min.fromList xs) == Min.fromList (map (+1) xs) validMinFilter :: [Int] -> Bool validMinFilter xs = Min.filter even (Min.fromList xs) == Min.fromList (List.filter even xs) validMinPartition :: [Int] -> Bool validMinPartition xs = Min.partition even (Min.fromList xs) == (let (xs1, xs2) = List.partition even xs in (Min.fromList xs1, Min.fromList xs2)) validMinCmp :: [Int] -> [Int] -> Bool validMinCmp xs1 xs2 = compare (Min.fromList xs1) (Min.fromList xs2) == compare (List.sort xs1) (List.sort xs2) validMinCmp2 :: [Int] -> Bool validMinCmp2 xs = compare (Min.fromList ys) (Min.fromList (take 30 ys)) == compare ys (take 30 ys) where ys = List.sort xs validSpan :: [Int] -> Bool validSpan xs = (Min.takeWhile even q, Min.dropWhile even q) == Min.span even q where q = Min.fromList xs validSpan2 :: [Int] -> Bool validSpan2 xs = second Min.toAscList (Min.span even (Min.fromList xs)) == List.span even (List.sort xs) validSplit :: Int -> [Int] -> Bool validSplit n xs = Min.splitAt n q == (Min.take n q, Min.drop n q) where q = Min.fromList xs validSplit2 :: Int -> [Int] -> Bool validSplit2 n xs = case Min.splitAt n (Min.fromList xs) of (ys, q') -> (ys, Min.toAscList q') == List.splitAt n (List.sort xs) validMapEither :: [Int] -> Bool validMapEither xs = Min.mapEither collatz q == (Min.mapMaybe (either Just (const Nothing) . collatz) q, Min.mapMaybe (either (const Nothing) Just . collatz) q) where q = Min.fromList xs validMap :: [Int] -> Bool validMap xs = Min.map f (Min.fromList xs) == Min.fromList (List.map f xs) where f = either id id . collatz collatz :: Int -> Either Int Int collatz x = if even x then Left $ x `quot` 2 else Right $ 3 * x + 1 validSize :: [Int] -> Bool validSize xs = Min.size q == List.length xs' where q = Min.drop 10 (Min.fromList xs) xs' = List.drop 10 (List.sort xs) validNull :: Int -> [Int] -> Bool validNull n xs = Min.null q == List.null xs' where q = Min.drop n (Min.fromList xs) xs' = List.drop n (List.sort xs) validFoldl :: [Int] -> Bool validFoldl xs = Min.foldlAsc (flip (:)) [] (Min.fromList xs) == List.foldl (flip (:)) [] (List.sort xs) validFoldlU :: [Int] -> Bool validFoldlU xs = Min.foldlU (flip (:)) [] q == List.reverse (Min.foldrU (:) [] q) where q = Min.fromList xs validFoldrU :: [Int] -> Bool validFoldrU xs = Min.foldrU (+) 0 q == List.sum xs where q = Min.fromList xs main :: IO () main = do check validMinToAscList check validMinToDescList check validMinUnfoldr check validMinToList check validMinFromAscList check validMinFromDescList check validMinUnion check validMinMapMonotonic check validMinPartition check validMinCmp check validMinCmp2 check validSpan check validSpan2 check validSplit check validSplit2 check validMinFilter check validMapEither check validMap check validSize check validNull check validFoldl check validFoldlU check validFoldrU isPass :: Result -> Bool isPass Success{} = True isPass _ = False check :: Testable prop => prop -> IO () check p = do r <- quickCheckResult p if isPass r then return () else exitFailure