module BuildBox.Aspect.Stats ( Stats (..) , makeStats , predStats , liftStats , liftStats2) where import BuildBox.Pretty import BuildBox.Data.Dividable -- | Statistics extracted from many-valued data. data Stats a = Stats { statsMin :: a , statsAvg :: a , statsMax :: a } deriving (Read, Show) instance Pretty a => Pretty (Stats a) where ppr (Stats mi av mx) = (ppr mi) <+> text "/" <+> (ppr av) <+> text "/" <+> (ppr mx) -- | Make statistics from a list of values. makeStats :: (Real a, Dividable a) => [a] -> Stats a makeStats xs = Stats (minimum xs) (sum xs `divide` (fromIntegral $ length xs)) (maximum xs) -- | Return `True` if the predicate matches any of the min, avg, max values. predStats :: (a -> Bool) -> Stats a -> Bool predStats f (Stats mi av mx) = or [f mi, f av, f mx] -- | Lift a function to each component of a `Stats` liftStats :: (a -> b) -> Stats a -> Stats b liftStats f (Stats mi av mx) = Stats (f mi) (f av) (f mx) -- | Lift a binary function to each component of a `Stats` liftStats2 :: (a -> b -> c) -> Stats a -> Stats b -> Stats c liftStats2 f (Stats min1 avg1 max1) (Stats min2 avg2 max2) = Stats (f min1 min2) (f avg1 avg2) (f max1 max2)