{-# 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 :: Int -> (a -> b) -> IO ()
classStats Int
n a -> b
f = String -> IO ()
putStrLn
(String -> IO ())
-> ([(String, Int)] -> String) -> [(String, Int)] -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [[String]] -> String
table String
" "
([[String]] -> String)
-> ([(String, Int)] -> [[String]]) -> [(String, Int)] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, Int) -> [String]) -> [(String, Int)] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map (String, Int) -> [String]
showCount
([(String, Int)] -> IO ()) -> [(String, Int)] -> IO ()
forall a b. (a -> b) -> a -> b
$ (a -> String) -> [a] -> [(String, Int)]
forall b a. Eq b => (a -> b) -> [a] -> [(b, Int)]
countsOn (String -> String
unquote (String -> String) -> (a -> String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> String
forall a. Show a => a -> String
show (b -> String) -> (a -> b) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) [a]
xs
where
xs :: [a]
xs = Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
n [a]
forall a. Listable a => [a]
list
len :: Int
len = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs
showCount :: (String, Int) -> [String]
showCount (String
s,Int
n) = [ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":"
, Int -> String
forall a. Show a => a -> String
show Int
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
len
, Int -> String
forall a. Show a => a -> String
show (Int
100 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
len) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"%"
]
classStatsT :: (Listable a, Show b) => Int -> (a -> b) -> IO ()
classStatsT :: Int -> (a -> b) -> IO ()
classStatsT Int
n a -> b
f = String -> IO ()
putStrLn
(String -> IO ()) -> ([[a]] -> String) -> [[a]] -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [[String]] -> String
table String
" "
([[String]] -> String) -> ([[a]] -> [[String]]) -> [[a]] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String]
heading[String] -> [[String]] -> [[String]]
forall a. a -> [a] -> [a]
:)
([[String]] -> [[String]])
-> ([[a]] -> [[String]]) -> [[a]] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String
" "][String] -> [[String]] -> [[String]]
forall a. a -> [a] -> [a]
:)
([[String]] -> [[String]])
-> ([[a]] -> [[String]]) -> [[a]] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, Int, [Int]) -> [String])
-> [(String, Int, [Int])] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map (String, Int, [Int]) -> [String]
forall a a. (Show a, Show a) => (String, a, [a]) -> [String]
showCounts
([(String, Int, [Int])] -> [[String]])
-> ([[a]] -> [(String, Int, [Int])]) -> [[a]] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(String, Int, [Int])] -> [(String, Int, [Int])]
prependTotal
([(String, Int, [Int])] -> [(String, Int, [Int])])
-> ([[a]] -> [(String, Int, [Int])])
-> [[a]]
-> [(String, Int, [Int])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> String) -> [[a]] -> [(String, Int, [Int])]
forall b a. Eq b => (a -> b) -> [[a]] -> [(b, Int, [Int])]
countsTOn (String -> String
unquote (String -> String) -> (a -> String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> String
forall a. Show a => a -> String
show (b -> String) -> (a -> b) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f)
([[a]] -> IO ()) -> [[a]] -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> [[a]] -> [[a]]
forall a. Int -> [a] -> [a]
take Int
n [[a]]
forall a. Listable a => [[a]]
tiers
where
heading :: [String]
heading = String
"" String -> [String] -> [String]
forall a. a -> [a] -> [a]
: String
"tot " String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (Int -> String) -> [Int] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Int -> String
forall a. Show a => a -> String
show [Int
0..(Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)]
showCounts :: (String, a, [a]) -> [String]
showCounts (String
s,a
n,[a]
ns) = (String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":") String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (a -> String
forall a. Show a => a -> String
show a
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" ") String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (a -> String) -> [a] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map a -> String
forall a. Show a => a -> String
show [a]
ns
(a
_,b
n,[c]
ns) -+- :: (a, b, [c]) -> (a, b, [c]) -> (String, b, [c])
-+- (a
_,b
n',[c]
ns') = (String
"tot", b
n b -> b -> b
forall a. Num a => a -> a -> a
+ b
n', (c -> c -> c) -> [c] -> [c] -> [c]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith c -> c -> c
forall a. Num a => a -> a -> a
(+) [c]
ns [c]
ns')
totalizeCounts :: [(a, Int, [Int])] -> (String, Int, [Int])
totalizeCounts = ((a, Int, [Int]) -> (String, Int, [Int]) -> (String, Int, [Int]))
-> (String, Int, [Int])
-> [(a, Int, [Int])]
-> (String, Int, [Int])
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (a, Int, [Int]) -> (String, Int, [Int]) -> (String, Int, [Int])
forall b c a a.
(Num b, Num c) =>
(a, b, [c]) -> (a, b, [c]) -> (String, b, [c])
(-+-) (String
forall a. HasCallStack => a
undefined, Int
0, Int -> [Int]
forall a. a -> [a]
repeat Int
0)
prependTotal :: [(String, Int, [Int])] -> [(String, Int, [Int])]
prependTotal [(String, Int, [Int])]
cs = [(String, Int, [Int])] -> (String, Int, [Int])
forall a. [(a, Int, [Int])] -> (String, Int, [Int])
totalizeCounts [(String, Int, [Int])]
cs (String, Int, [Int])
-> [(String, Int, [Int])] -> [(String, Int, [Int])]
forall a. a -> [a] -> [a]
: [(String, Int, [Int])]
cs
conditionStats :: Listable a => Int -> [(String,a->Bool)] -> IO ()
conditionStats :: Int -> [(String, a -> Bool)] -> IO ()
conditionStats Int
n = String -> IO ()
putStrLn (String -> IO ())
-> ([(String, a -> Bool)] -> String)
-> [(String, a -> Bool)]
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [[String]] -> String
table String
" " ([[String]] -> String)
-> ([(String, a -> Bool)] -> [[String]])
-> [(String, a -> Bool)]
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, a -> Bool) -> [String])
-> [(String, a -> Bool)] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map (String, a -> Bool) -> [String]
show1
where
xs :: [a]
xs = Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
n [a]
forall a. Listable a => [a]
list
len :: Int
len = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs
show1 :: (String, a -> Bool) -> [String]
show1 (String
s,a -> Bool
f) = let c :: Int
c = (a -> Bool) -> [a] -> Int
forall a. (a -> Bool) -> [a] -> Int
count a -> Bool
f [a]
xs
in [ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":"
, Int -> String
forall a. Show a => a -> String
show Int
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
len
, Int -> String
forall a. Show a => a -> String
show (Int
100 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
c Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
len) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"%" ]
count :: (a -> Bool) -> [a] -> Int
count a -> Bool
f = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([a] -> Int) -> ([a] -> [a]) -> [a] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter a -> Bool
f
conditionStatsT :: Listable a => Int -> [(String,a->Bool)] -> IO ()
conditionStatsT :: Int -> [(String, a -> Bool)] -> IO ()
conditionStatsT Int
n = String -> IO ()
putStrLn (String -> IO ())
-> ([(String, a -> Bool)] -> String)
-> [(String, a -> Bool)]
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [[String]] -> String
table String
" " ([[String]] -> String)
-> ([(String, a -> Bool)] -> [[String]])
-> [(String, a -> Bool)]
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, a -> Bool) -> [String])
-> [(String, a -> Bool)] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map (String, a -> Bool) -> [String]
show1 ([(String, a -> Bool)] -> [[String]])
-> ([(String, a -> Bool)] -> [(String, a -> Bool)])
-> [(String, a -> Bool)]
-> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String
"total", Bool -> a -> Bool
forall a b. a -> b -> a
const Bool
True)(String, a -> Bool)
-> [(String, a -> Bool)] -> [(String, a -> Bool)]
forall a. a -> [a] -> [a]
:)
where
xss :: [[a]]
xss = Int -> [[a]] -> [[a]]
forall a. Int -> [a] -> [a]
take Int
n [[a]]
forall a. Listable a => [[a]]
tiers
show1 :: (String, a -> Bool) -> [String]
show1 (String
s,a -> Bool
f) = (String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":") String -> [String] -> [String]
forall a. a -> [a] -> [a]
: ([a] -> String) -> [[a]] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> String
forall a. Show a => a -> String
show (Int -> String) -> ([a] -> Int) -> [a] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> [a] -> Int
forall a. (a -> Bool) -> [a] -> Int
count a -> Bool
f) [[a]]
xss
count :: (a -> Bool) -> [a] -> Int
count a -> Bool
f = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([a] -> Int) -> ([a] -> [a]) -> [a] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter a -> Bool
f
classify :: Eq a => [a] -> [[a]]
classify :: [a] -> [[a]]
classify = (a -> a -> Bool) -> [a] -> [[a]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
classifyBy a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(==)
classifyBy :: (a -> a -> Bool) -> [a] -> [[a]]
classifyBy :: (a -> a -> Bool) -> [a] -> [[a]]
classifyBy a -> a -> Bool
(==) [] = []
classifyBy a -> a -> Bool
(==) (a
x:[a]
xs) = (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:(a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter (a -> a -> Bool
== a
x) [a]
xs)
[a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: (a -> a -> Bool) -> [a] -> [[a]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
classifyBy a -> a -> Bool
(==) ((a -> Bool) -> [a] -> [a]
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 :: (a -> b) -> [a] -> [[a]]
classifyOn a -> b
f [a]
xs = ([(a, b)] -> [a]) -> [[(a, b)]] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map (((a, b) -> a) -> [(a, b)] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (a, b) -> a
forall a b. (a, b) -> a
fst)
([[(a, b)]] -> [[a]])
-> ([(a, b)] -> [[(a, b)]]) -> [(a, b)] -> [[a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, b) -> (a, b) -> Bool) -> [(a, b)] -> [[(a, b)]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
classifyBy (b -> b -> Bool
forall a. Eq a => a -> a -> Bool
(==) (b -> b -> Bool) -> ((a, b) -> b) -> (a, b) -> (a, b) -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (a, b) -> b
forall a b. (a, b) -> b
snd)
([(a, b)] -> [[a]]) -> [(a, b)] -> [[a]]
forall a b. (a -> b) -> a -> b
$ (a -> (a, b)) -> [a] -> [(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 :: [a] -> [(a, Int)]
counts = ([a] -> (a, Int)) -> [[a]] -> [(a, Int)]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> (a, Int)
forall a. [a] -> (a, Int)
headLength ([[a]] -> [(a, Int)]) -> ([a] -> [[a]]) -> [a] -> [(a, Int)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [[a]]
forall a. Eq a => [a] -> [[a]]
classify
countsBy :: (a -> a -> Bool) -> [a] -> [(a,Int)]
countsBy :: (a -> a -> Bool) -> [a] -> [(a, Int)]
countsBy a -> a -> Bool
(==) = ([a] -> (a, Int)) -> [[a]] -> [(a, Int)]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> (a, Int)
forall a. [a] -> (a, Int)
headLength ([[a]] -> [(a, Int)]) -> ([a] -> [[a]]) -> [a] -> [(a, Int)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> a -> Bool) -> [a] -> [[a]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
classifyBy a -> a -> Bool
(==)
countsOn :: Eq b => (a -> b) -> [a] -> [(b,Int)]
countsOn :: (a -> b) -> [a] -> [(b, Int)]
countsOn a -> b
f = ([a] -> (b, Int)) -> [[a]] -> [(b, Int)]
forall a b. (a -> b) -> [a] -> [b]
map (\[a]
xs -> (a -> b
f (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$ [a] -> a
forall a. [a] -> a
head [a]
xs, [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs)) ([[a]] -> [(b, Int)]) -> ([a] -> [[a]]) -> [a] -> [(b, Int)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> [a] -> [[a]]
forall b a. Eq b => (a -> b) -> [a] -> [[a]]
classifyOn a -> b
f
countsT :: Eq a => [[a]] -> [(a,Int,[Int])]
countsT :: [[a]] -> [(a, Int, [Int])]
countsT [[a]]
xss = [(a
x,Int
n,([a] -> Int) -> [[a]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (a -> [a] -> Int
forall a. Eq a => a -> [a] -> Int
count a
x) [[a]]
xss) | (a
x,Int
n) <- [a] -> [(a, Int)]
forall a. Eq a => [a] -> [(a, Int)]
counts ([[a]] -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[a]]
xss)]
where
count :: a -> [a] -> Int
count a
x = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([a] -> Int) -> ([a] -> [a]) -> [a] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter (a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
x)
countsTOn :: Eq b => (a -> b) -> [[a]] -> [(b,Int,[Int])]
countsTOn :: (a -> b) -> [[a]] -> [(b, Int, [Int])]
countsTOn a -> b
f = [[b]] -> [(b, Int, [Int])]
forall a. Eq a => [[a]] -> [(a, Int, [Int])]
countsT ([[b]] -> [(b, Int, [Int])])
-> ([[a]] -> [[b]]) -> [[a]] -> [(b, Int, [Int])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> [[a]] -> [[b]]
forall a b. (a -> b) -> [[a]] -> [[b]]
mapT a -> b
f
headLength :: [a] -> (a,Int)
headLength :: [a] -> (a, Int)
headLength [a]
xs = ([a] -> a
forall a. [a] -> a
head [a]
xs, [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs)
unquote :: String -> String
unquote :: String -> String
unquote (Char
'"':String
s) | String -> Char
forall a. [a] -> a
last String
s Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'"' = String -> String
forall a. [a] -> [a]
init String
s
unquote String
s = String
s
table :: String -> [[String]] -> String
table :: String -> [[String]] -> String
table String
s [] = String
""
table String
s [[String]]
sss = [String] -> String
unlines
([String] -> String)
-> ([[String]] -> [String]) -> [[String]] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Char -> String -> String
forall a. Eq a => a -> [a] -> [a]
removeTrailing Char
' ')
([String] -> [String])
-> ([[String]] -> [String]) -> [[String]] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String] -> String) -> [[String]] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
s)
([[String]] -> [String])
-> ([[String]] -> [[String]]) -> [[String]] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[String]] -> [[String]]
forall a. [[a]] -> [[a]]
transpose
([[String]] -> [[String]])
-> ([[String]] -> [[String]]) -> [[String]] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String] -> [String]) -> [[String]] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map (Char -> [String] -> [String]
forall a. a -> [[a]] -> [[a]]
normalize Char
' ')
([[String]] -> [[String]])
-> ([[String]] -> [[String]]) -> [[String]] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([[String]] -> [[String]] -> [[String]])
-> [[[String]]] -> [[String]]
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 (([String] -> [String] -> [String])
-> [[String]] -> [[String]] -> [[String]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
(++))
([[[String]]] -> [[String]])
-> ([[String]] -> [[[String]]]) -> [[String]] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String] -> [[String]]) -> [[String]] -> [[[String]]]
forall a b. (a -> b) -> [a] -> [b]
map (String -> [[String]] -> [[String]]
forall a. a -> [[a]] -> [[a]]
normalize String
"" ([[String]] -> [[String]])
-> ([String] -> [[String]]) -> [String] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> [String]) -> [String] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map String -> [String]
lines)
([[String]] -> [[[String]]])
-> ([[String]] -> [[String]]) -> [[String]] -> [[[String]]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [[String]] -> [[String]]
forall a. a -> [[a]] -> [[a]]
normalize String
""
([[String]] -> String) -> [[String]] -> String
forall a b. (a -> b) -> a -> b
$ [[String]]
sss
fit :: a -> Int -> [a] -> [a]
fit :: a -> Int -> [a] -> [a]
fit a
x Int
n [a]
xs = Int -> a -> [a]
forall a. Int -> a -> [a]
replicate (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs) a
x [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a]
xs
normalize :: a -> [[a]] -> [[a]]
normalize :: a -> [[a]] -> [[a]]
normalize a
x [[a]]
xs = ([a] -> [a]) -> [[a]] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map (a
x a -> Int -> [a] -> [a]
forall a. a -> Int -> [a] -> [a]
`fit` [[a]] -> Int
forall a. [[a]] -> Int
maxLength [[a]]
xs) [[a]]
xs
maxLength :: [[a]] -> Int
maxLength :: [[a]] -> Int
maxLength = [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Int] -> Int) -> ([[a]] -> [Int]) -> [[a]] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int
0Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
:) ([Int] -> [Int]) -> ([[a]] -> [Int]) -> [[a]] -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> Int) -> [[a]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length
removeTrailing :: Eq a => a -> [a] -> [a]
removeTrailing :: a -> [a] -> [a]
removeTrailing a
x = [a] -> [a]
forall a. [a] -> [a]
reverse
([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (a -> a -> Bool
forall a. Eq a => a -> a -> Bool
==a
x)
([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a]
forall a. [a] -> [a]
reverse