-- | -- Module : Test.Speculate.Utils.Misc -- Copyright : (c) 2016-2019 Rudy Matela -- License : 3-Clause BSD (see the file LICENSE) -- Maintainer : Rudy Matela -- -- This module is part of Speculate. -- -- Miscellaneous utilities. module Test.Speculate.Utils.Misc where import Data.Maybe import Data.Ratio import Test.Speculate.Utils.String import Test.Speculate.Utils.List -- easy debug: undefined1 :: a undefined1 = error "undefined1" undefined2 :: a undefined2 = error "undefined2" thn :: Ordering -> Ordering -> Ordering thn EQ o = o thn o _ = o infixr 8 `thn` -- TODO: Remove this function in favour of LeanCheck's classStats reportCountsBy :: (Eq b, Show b) => (a -> b) -> [a] -> IO () reportCountsBy f xs = putStrLn . unlines . map showCount $ countsOn f xs where len = length xs showCount (x,n) = unquote (show x) ++ ": " ++ show n ++ "/" ++ show len ++ " " ++ show (100 * n `div` len) ++ "%" maybesToMaybe :: [Maybe a] -> Maybe a maybesToMaybe = listToMaybe . catMaybes maybe2 :: c -> (a -> b -> c) -> Maybe a -> Maybe b -> c maybe2 _ f (Just x) (Just y) = f x y maybe2 z _ _ _ = z iterateUntil :: (a -> a -> Bool) -> (a -> a) -> a -> a iterateUntil p f x = let fx = f x in if x `p` fx then x else iterateUntil p f fx iterateUntilLimit :: Int -> (a -> a -> Bool) -> (a -> a) -> a -> a iterateUntilLimit 0 p f x = x iterateUntilLimit n p f x = let fx = f x in if x `p` fx then x else iterateUntilLimit (n-1) p f fx showRatio :: (Integral a, Show a) => Ratio a -> String showRatio r = show (numerator r) ++ "/" ++ show (denominator r) percent :: Integral a => Ratio a -> a percent r = numerator r * 100 `div` denominator r putLines :: [String] -> IO () putLines [] = return () putLines ls = putStrLn (unlines ls) (.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d (.:) = (.) . (.) (..:) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e (..:) = (.) . (.:)