-- taxes.hs -- L. David Baron , 2008-03-16 -- -- Figure changes in marginal tax rates for a single Californian earning -- all income from wages. -- -- This is actually my first Haskell program, so don't be too harsh! module TaxRates where import Text.Printf ss_tax income = 0.062 * (min income 97500) medicare_tax income = 0.0145 * income cal_sdi_tax income = 0.006 * (min income 83388.333333333333) cal_deduction income = 3516 -- Technically more correct, but unused cal_exemption_discrete income = max (94 - (6 * fromInteger (round ((max (income - 155416) 0) / 2500)))) 0 cal_exemption income = max (94 - (6 * (max (income - 155416) 0) / 2500)) 0 cal_income_tax income = let agi = income - (cal_deduction income) ia = min agi 6827 ib = (min agi 16185) - ia ic = (min agi 25544) - ia - ib id = (min agi 35460) - ia - ib - ic ie = (min agi 44814) - ia - ib - ic - id ig = agi - ia - ib - ic - id - ie tax = 0.01 * ia + 0.02 * ib + 0.04 * ic + 0.06 * id + 0.08 * ie + 0.093 * ig in max (tax - (cal_exemption income)) 0 cal_total_tax income = (cal_sdi_tax income) + (cal_income_tax income) federal_deduction income = let itemizedunlimited = cal_total_tax income limit = (min (0.8 * itemizedunlimited) ((max 0 (income - 156400)) * 0.03)) * (2 / 3) itemized = itemizedunlimited - limit in max itemized 5350 -- Technically more correct, but unused federal_exemption_discrete income = if (income > (156400 + 122500)) then 1133 else 3400 * (1 - (fromInteger (max 0 (ceiling ((income - 156400) / 2500)))) * (2 / 150)) federal_exemption income = max 1133 (3400 * (1 - (max 0 ((income - 156400) / 2500)) * (2 / 150))) federal_eic income = -- This is a lot higher for people with kids. min (min (income * 0.0765) 428) (max 0 ((12590 - income) * 0.0765)) federal_regular_income_tax income = let ti = income - (federal_deduction income) - (federal_exemption income) ia = (min ti 7825) ib = (min ti 31850) - ia ic = (min ti 77100) - ia - ib id = (min ti 160850) - ia - ib - ic ie = (min ti 349700) - ia - ib - ic - id ig = ti - ia - ib - ic - id - ie in ia * 0.1 + ib * 0.15 + ic * 0.25 + id * 0.28 + ie * 0.33 + ig * 0.35 federal_amt_exemption income = max 0 (44350 - 0.25 * (max 0 (income - 112500))) federal_amt income = let amti = max 0 (income - (federal_amt_exemption income)) in if amti < 175000 then 0.26 * amti else (0.28 * amti) - 3500 federal_income_tax income = max (federal_regular_income_tax income) (federal_amt income) total_tax income = (cal_total_tax income) + (federal_income_tax income) + (ss_tax income) + (medicare_tax income) - (federal_eic income) rate tax income = 100 * (tax (income + 0.01) - tax income) to_nearest_cents dollars = (fromInteger (round (dollars * 100))) / 100 marginal_rate_table_points tax incomel incomeh = let ratel = rate tax incomel rateh = rate tax incomeh in -- Continue the search if (a) there is a rate difference that we're -- trying to narrow, or (b) in case the rate jumps back to the same -- amount, the low and high incomes are separated by more than 1% -- and more than $100. if (abs (rateh - ratel) >= 0.0001) || ((incomeh - incomel > 100) && ((incomeh - incomel) / incomel > 0.01)) then let incomec = to_nearest_cents ((incomeh + incomel) / 2) in if incomel == incomec || incomec == incomeh then [incomeh] else (marginal_rate_table_points tax incomel incomec) ++ (marginal_rate_table_points tax incomec incomeh) else [] marginal_rate_table_string tax incomel incomeh = let point_string tax income = printf ("At income $%.2f where tax is $%.2f\n" ++ " rate changes from %.5f%%%% to %.5f%%%%.\n") income (tax income) ((rate tax (income - 0.01)) * 100) ((rate tax income) * 100) between_points_string tax incomea incomeb = printf ("Between income $%.2f and income $%.2f where tax is $%.2f\n" ++ " rate changes from %.5f%%%% to %.5f%%%%.\n") incomea incomeb (tax incomeb) ((rate tax (incomea - 0.01)) * 100) ((rate tax incomeb) * 100) points_string tax [] = "" points_string tax (point:[]) = point_string tax point points_string tax (pointa:pointb:rest) = if pointb - pointa <= 0.011 then (between_points_string tax pointa pointb) ++ (points_string tax rest) else (point_string tax pointa) ++ (points_string tax (pointb:rest)) in points_string tax (marginal_rate_table_points tax incomel incomeh) -- printf (marginal_rate_table_string total_tax 0 10000000)