import Data.Function ((&))
import Text.Printf
data SaleSum = SaleSum {
totalCost :: Double,
totalQuantity :: Int
}
class SaleSummary s where
summary :: s -> SaleSum
instance Semigroup SaleSum where
(SaleSum c1 q1) <> (SaleSum c2 q2) = SaleSum (c1 + c2) (q1 + q2)
instance Monoid SaleSum where
mempty = SaleSum 0.0 0
instance Show SaleSum where
show (SaleSum cost quantity) =
"Total cost = " ++ printf "%.2f" cost ++ ", quantity = " ++ show quantity
totalSummary :: SaleSummary s => [s] -> SaleSum
totalSummary xs = xs & map summary & mconcat
----------------------------------------------------------------
data Sale = Sale {
itemID :: String,
price :: Double,
quantity :: Int
-- maybe some other fields
}
instance SaleSummary Sale where
summary s = SaleSum (price s * fromIntegral (quantity s)) (quantity s)
testSales = [
Sale "Foo" 0.20 4,
Sale "Bar" 1.10 3
]
main = print $ totalSummary testSales