Nutri-0.1: src/Data/Nutrition/Macros.hs
{-# OPTIONS_HADDOCK prune, ignore-exports #-}
module Data.Nutrition.Macros
(
Macros ()
, newMacros
, prot
, carb
, fat
)
where
import Control.Category
type Percent = Float
type Protein = Percent
type Carb = Percent
type Fat = Percent
-- | The macro nutrients are @Protein@, @Carbohydrate@ and @Fat@. They
-- are stored within a triple that is called 'Macros'.
data Macros = Macros (Protein, Carb, Fat)
-- | 'prot', 'carb' and 'fat' are functions that return the percent of
-- that macro nutrient. They are basically getters of the 'Macros'
-- data.
prot, fat, carb :: Macros -> Percent
prot (Macros (p, _, _)) = p
carb (Macros (_, c, _)) = c
fat (Macros (_, _, f)) = f
-- | 'newMacros' is a smart constructor to 'Macros'. It checks,
-- whether the sum of the percentages is equal or below
-- 100%. Otherwise it does not construct a 'Macros' value.
newMacros :: (Protein, Carb, Fat) -> Macros
newMacros (p, c, f)
| (p + c + f) <= 100 = Macros (p, c, f)
| otherwise = error $ "macro definition exeeds 100%"
-- instance Num Macros where
-- m1 + m2 = newMacros $ percentualDo (+) (prot m1, carb m1, fat m1) (prot m2, carb m2, fat m2)
-- m1 - m2 = newMacros $ percentualDo (-) (prot m1, carb m1, fat m1) (prot m2, carb m2, fat m2)
-- (*) = error "this operation isn't defined on macros"
-- percentualDo op (p1, c1, f1) (p2, c2, f2)
-- = (p, c, f)
-- where sum1 = p1 + c1 + f1
-- sum2 = p2 + c2 + f2
-- percentCalc op sum1 sum2 v1 v2
-- = (v1 * 100.0 / sum1) `op` (v2 * 100.0 / sum2) / 2
-- p = percentCalc op sum1 sum2 p1 p2
-- c = percentCalc op sum1 sum2 c1 c2
-- f = percentCalc op sum1 sum2 f1 f2