{-# LANGUAGE CPP #-}
module Test.LeanCheck.Stats
( classStats
, classStatsT
, conditionStats
, conditionStatsT
, classify
, classifyBy
, classifyOn
, counts
, countsBy
, countsOn
)
where
import Test.LeanCheck.Core
import Data.Function (on)
#ifndef __HUGS__
import Data.List (intercalate, transpose)
#else
import Data.List (transpose)
intercalate :: [a] -> [[a]] -> [a]
intercalate xs xss = concat (intersperse xs xss)
where
intersperse :: a -> [a] -> [a]
intersperse _ [] = []
intersperse sep (x:xs) = x : prependToAll sep xs
where
prependToAll :: a -> [a] -> [a]
prependToAll _ [] = []
prependToAll sep (x:xs) = sep : x : prependToAll sep xs
#endif
classStats :: (Listable a, Show b) => Int -> (a -> b) -> IO ()
classStats :: forall a b. (Listable a, Show b) => Int -> (a -> b) -> IO ()
classStats Int
n a -> b
f = [Char] -> IO ()
putStrLn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [[[Char]]] -> [Char]
table [Char]
" "
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map ([Char], Int) -> [[Char]]
showCount
forall a b. (a -> b) -> a -> b
$ forall b a. Eq b => (a -> b) -> [a] -> [(b, Int)]
countsOn ([Char] -> [Char]
unquote forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> [Char]
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) [a]
xs
where
xs :: [a]
xs = forall a. Int -> [a] -> [a]
take Int
n forall a. Listable a => [a]
list
len :: Int
len = forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs
showCount :: ([Char], Int) -> [[Char]]
showCount ([Char]
s,Int
n) = [ [Char]
s forall a. [a] -> [a] -> [a]
++ [Char]
":"
, forall a. Show a => a -> [Char]
show Int
n forall a. [a] -> [a] -> [a]
++ [Char]
"/" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
len
, forall a. Show a => a -> [Char]
show (Int
100 forall a. Num a => a -> a -> a
* Int
n forall a. Integral a => a -> a -> a
`div` Int
len) forall a. [a] -> [a] -> [a]
++ [Char]
"%"
]
classStatsT :: (Listable a, Show b) => Int -> (a -> b) -> IO ()
classStatsT :: forall a b. (Listable a, Show b) => Int -> (a -> b) -> IO ()
classStatsT Int
n a -> b
f = [Char] -> IO ()
putStrLn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [[[Char]]] -> [Char]
table [Char]
" "
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([[Char]]
headingforall a. a -> [a] -> [a]
:)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([[Char]
" "]forall a. a -> [a] -> [a]
:)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall {a} {a}. (Show a, Show a) => ([Char], a, [a]) -> [[Char]]
showCounts
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [([Char], Int, [Int])] -> [([Char], Int, [Int])]
prependTotal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. Eq b => (a -> b) -> [[a]] -> [(b, Int, [Int])]
countsTOn ([Char] -> [Char]
unquote forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> [Char]
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f)
forall a b. (a -> b) -> a -> b
$ forall a. Int -> [a] -> [a]
take Int
n forall a. Listable a => [[a]]
tiers
where
heading :: [[Char]]
heading = [Char]
"" forall a. a -> [a] -> [a]
: [Char]
"tot " forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map forall a. Show a => a -> [Char]
show [Int
0..(Int
nforall a. Num a => a -> a -> a
-Int
1)]
showCounts :: ([Char], a, [a]) -> [[Char]]
showCounts ([Char]
s,a
n,[a]
ns) = ([Char]
s forall a. [a] -> [a] -> [a]
++ [Char]
":") forall a. a -> [a] -> [a]
: (forall a. Show a => a -> [Char]
show a
n forall a. [a] -> [a] -> [a]
++ [Char]
" ") forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map forall a. Show a => a -> [Char]
show [a]
ns
(a
_,b
n,[c]
ns) -+- :: (a, b, [c]) -> (a, b, [c]) -> ([Char], b, [c])
-+- (a
_,b
n',[c]
ns') = ([Char]
"tot", b
n forall a. Num a => a -> a -> a
+ b
n', forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. Num a => a -> a -> a
(+) [c]
ns [c]
ns')
totalizeCounts :: [(a, Int, [Int])] -> ([Char], Int, [Int])
totalizeCounts = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall {b} {c} {a} {a}.
(Num b, Num c) =>
(a, b, [c]) -> (a, b, [c]) -> ([Char], b, [c])
(-+-) (forall a. HasCallStack => a
undefined, Int
0, forall a. a -> [a]
repeat Int
0)
prependTotal :: [([Char], Int, [Int])] -> [([Char], Int, [Int])]
prependTotal [([Char], Int, [Int])]
cs = forall {a}. [(a, Int, [Int])] -> ([Char], Int, [Int])
totalizeCounts [([Char], Int, [Int])]
cs forall a. a -> [a] -> [a]
: [([Char], Int, [Int])]
cs
conditionStats :: Listable a => Int -> [(String,a->Bool)] -> IO ()
conditionStats :: forall a. Listable a => Int -> [([Char], a -> Bool)] -> IO ()
conditionStats Int
n = [Char] -> IO ()
putStrLn forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [[[Char]]] -> [Char]
table [Char]
" " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map ([Char], a -> Bool) -> [[Char]]
show1
where
xs :: [a]
xs = forall a. Int -> [a] -> [a]
take Int
n forall a. Listable a => [a]
list
len :: Int
len = forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs
show1 :: ([Char], a -> Bool) -> [[Char]]
show1 ([Char]
s,a -> Bool
f) = [ [Char]
s forall a. [a] -> [a] -> [a]
++ [Char]
":"
, forall a. Show a => a -> [Char]
show Int
c forall a. [a] -> [a] -> [a]
++ [Char]
"/" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
len
, forall a. Show a => a -> [Char]
show (Int
100 forall a. Num a => a -> a -> a
* Int
c forall a. Integral a => a -> a -> a
`div` Int
len) forall a. [a] -> [a] -> [a]
++ [Char]
"%"
] where c :: Int
c = forall {a}. (a -> Bool) -> [a] -> Int
count a -> Bool
f [a]
xs
count :: (a -> Bool) -> [a] -> Int
count a -> Bool
f = forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter a -> Bool
f
conditionStatsT :: Listable a => Int -> [(String,a->Bool)] -> IO ()
conditionStatsT :: forall a. Listable a => Int -> [([Char], a -> Bool)] -> IO ()
conditionStatsT Int
n = [Char] -> IO ()
putStrLn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [[[Char]]] -> [Char]
table [Char]
" "
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map ([Char], a -> Bool) -> [[Char]]
show1
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([Char]
"total", forall a b. a -> b -> a
const Bool
True)forall a. a -> [a] -> [a]
:)
where
xss :: [[a]]
xss = forall a. Int -> [a] -> [a]
take Int
n forall a. Listable a => [[a]]
tiers
show1 :: ([Char], a -> Bool) -> [[Char]]
show1 ([Char]
s,a -> Bool
f) = ([Char]
s forall a. [a] -> [a] -> [a]
++ [Char]
":") forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map (forall a. Show a => a -> [Char]
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {a}. (a -> Bool) -> [a] -> Int
count a -> Bool
f) [[a]]
xss
count :: (a -> Bool) -> [a] -> Int
count a -> Bool
f = forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter a -> Bool
f
classify :: Eq a => [a] -> [[a]]
classify :: forall a. Eq a => [a] -> [[a]]
classify = forall a. (a -> a -> Bool) -> [a] -> [[a]]
classifyBy forall a. Eq a => a -> a -> Bool
(==)
classifyBy :: (a -> a -> Bool) -> [a] -> [[a]]
classifyBy :: forall a. (a -> a -> Bool) -> [a] -> [[a]]
classifyBy a -> a -> Bool
(==) [] = []
classifyBy a -> a -> Bool
(==) (a
x:[a]
xs) = (a
xforall a. a -> [a] -> [a]
:forall a. (a -> Bool) -> [a] -> [a]
filter (a -> a -> Bool
== a
x) [a]
xs)
forall a. a -> [a] -> [a]
: forall a. (a -> a -> Bool) -> [a] -> [[a]]
classifyBy a -> a -> Bool
(==) (forall a. (a -> Bool) -> [a] -> [a]
filter (a -> a -> Bool
/= a
x) [a]
xs)
where
a
x /= :: a -> a -> Bool
/= a
y = Bool -> Bool
not (a
x a -> a -> Bool
== a
y)
classifyOn :: Eq b => (a -> b) -> [a] -> [[a]]
classifyOn :: forall b a. Eq b => (a -> b) -> [a] -> [[a]]
classifyOn a -> b
f [a]
xs = forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> a -> Bool) -> [a] -> [[a]]
classifyBy (forall a. Eq a => a -> a -> Bool
(==) forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` forall a b. (a, b) -> b
snd)
forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (\a
x -> (a
x,a -> b
f a
x)) [a]
xs
counts :: Eq a => [a] -> [(a,Int)]
counts :: forall a. Eq a => [a] -> [(a, Int)]
counts = forall a b. (a -> b) -> [a] -> [b]
map forall a. [a] -> (a, Int)
headLength forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Eq a => [a] -> [[a]]
classify
countsBy :: (a -> a -> Bool) -> [a] -> [(a,Int)]
countsBy :: forall a. (a -> a -> Bool) -> [a] -> [(a, Int)]
countsBy a -> a -> Bool
(==) = forall a b. (a -> b) -> [a] -> [b]
map forall a. [a] -> (a, Int)
headLength forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> a -> Bool) -> [a] -> [[a]]
classifyBy a -> a -> Bool
(==)
countsOn :: Eq b => (a -> b) -> [a] -> [(b,Int)]
countsOn :: forall b a. Eq b => (a -> b) -> [a] -> [(b, Int)]
countsOn a -> b
f = forall a b. (a -> b) -> [a] -> [b]
map (\[a]
xs -> (a -> b
f forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
head [a]
xs, forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. Eq b => (a -> b) -> [a] -> [[a]]
classifyOn a -> b
f
countsT :: Eq a => [[a]] -> [(a,Int,[Int])]
countsT :: forall a. Eq a => [[a]] -> [(a, Int, [Int])]
countsT [[a]]
xss = [(a
x,Int
n,forall a b. (a -> b) -> [a] -> [b]
map (forall {a}. Eq a => a -> [a] -> Int
count a
x) [[a]]
xss) | (a
x,Int
n) <- forall a. Eq a => [a] -> [(a, Int)]
counts (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[a]]
xss)]
where
count :: a -> [a] -> Int
count a
x = forall (t :: * -> *) a. Foldable t => t a -> Int
length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter (forall a. Eq a => a -> a -> Bool
== a
x)
countsTOn :: Eq b => (a -> b) -> [[a]] -> [(b,Int,[Int])]
countsTOn :: forall b a. Eq b => (a -> b) -> [[a]] -> [(b, Int, [Int])]
countsTOn a -> b
f = forall a. Eq a => [[a]] -> [(a, Int, [Int])]
countsT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [[a]] -> [[b]]
mapT a -> b
f
headLength :: [a] -> (a,Int)
headLength :: forall a. [a] -> (a, Int)
headLength [a]
xs = (forall a. [a] -> a
head [a]
xs, forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs)
unquote :: String -> String
unquote :: [Char] -> [Char]
unquote (Char
'"':[Char]
s) | forall a. [a] -> a
last [Char]
s forall a. Eq a => a -> a -> Bool
== Char
'"' = forall a. [a] -> [a]
init [Char]
s
unquote [Char]
s = [Char]
s
table :: String -> [[String]] -> String
table :: [Char] -> [[[Char]]] -> [Char]
table [Char]
s [] = [Char]
""
table [Char]
s [[[Char]]]
sss = [[Char]] -> [Char]
unlines
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall a. Eq a => a -> [a] -> [a]
removeTrailing Char
' ')
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall a. [a] -> [[a]] -> [a]
intercalate [Char]
s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [[a]] -> [[a]]
transpose
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall a. a -> [[a]] -> [[a]]
normalize Char
' ')
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 (forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. [a] -> [a] -> [a]
(++))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall a. a -> [[a]] -> [[a]]
normalize [Char]
"" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map [Char] -> [[Char]]
lines)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [[a]] -> [[a]]
normalize [Char]
""
forall a b. (a -> b) -> a -> b
$ [[[Char]]]
sss
fit :: a -> Int -> [a] -> [a]
fit :: forall a. a -> Int -> [a] -> [a]
fit a
x Int
n [a]
xs = forall a. Int -> a -> [a]
replicate (Int
n forall a. Num a => a -> a -> a
- forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs) a
x forall a. [a] -> [a] -> [a]
++ [a]
xs
normalize :: a -> [[a]] -> [[a]]
normalize :: forall a. a -> [[a]] -> [[a]]
normalize a
x [[a]]
xs = forall a b. (a -> b) -> [a] -> [b]
map (a
x forall a. a -> Int -> [a] -> [a]
`fit` forall a. [[a]] -> Int
maxLength [[a]]
xs) [[a]]
xs
maxLength :: [[a]] -> Int
maxLength :: forall a. [[a]] -> Int
maxLength = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int
0forall a. a -> [a] -> [a]
:) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall (t :: * -> *) a. Foldable t => t a -> Int
length
removeTrailing :: Eq a => a -> [a] -> [a]
removeTrailing :: forall a. Eq a => a -> [a] -> [a]
removeTrailing a
x = forall a. [a] -> [a]
reverse
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
dropWhile (forall a. Eq a => a -> a -> Bool
==a
x)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [a]
reverse