Alternative Calculation

Just like what I said in previous, there is other way to calculate.

Flatly

    0 until 50  million:  5%
>  50 until 250 million: 15% -  5 million
> 250 until 500 million: 25% - 30 million
> 500 million          : 30% - 55 million

This will hold the same result as previous:

  50 million:   2.5 million
 250 million:  32.5 million
 500 million:  95   million
1000 million: 245   million

Infographic Chart

The math for above equation derived as shown in figure below:

Haskell: Progressive Tax Tariff Chart


Haskell Code

Guard and Recursive

We can simply rephrase the previous function, as below to get the code done:

-- taxable income
pkp :: Int
pkp = 1000000000

-- income tax using progressive tariff
pph :: Int -> Int
pph pkp = round(pkpr pkp)
  where
    pkp_d  = fromIntegral(pkp)
    pkpr pkp
      | pkp <=  50000000 = pkp_d * 0.05
      | pkp <= 250000000 = pkp_d * 0.15 -  5000000
      | pkp <= 500000000 = pkp_d * 0.25 - 30000000
      | otherwise        = pkp_d * 0.30 - 55000000

main = putStrLn $ show $ pph pkp

Code above will also result as below

245000000

The code is very nice and intuitive. The only isuuse here is there are too many constant.

Can we make it simpler ?

Separating Constants

By taking out the constant, we can prepare this code below:

[t1, t2, t3, t4] = map (*million) [0, 50, 250, 500]
(d1, d2, d3, d4) = (0, 5, 30, 55)
[dj1, dj2, dj3, dj4] = [fromIntegral(x * million) | x <- [d1, d2, d3, d4]]
pkp_d   = fromIntegral(pkp)
million = 1000000

Or in a more complete fashion, put the prepared constant inside where clause.

-- taxable incomes
pkps :: [Int]
pkps = [10^7, 10^8, 10^9]

-- income tax using progressive tariff
pph :: Int -> Int
pph pkp = round(pkpr pkp)
  where 
    pkpr pkp
      | pkp > t4 = pkp_d * p4 - d4
      | pkp > t3 = pkp_d * p3 - d3
      | pkp > t2 = pkp_d * p2 - d2
      | pkp > t1 = pkp_d * p1 - d1
    -- guard limit
    [t1, t2, t3, t4] = map (*million) [0, 50, 250, 500]
    -- tariff rate in percent
    (p1, p2, p3, p4) = (0.05, 0.15, 0.25, 0.30)
    -- difference, in million rupiah
    [d1, d2, d3, d4] = map (fromIntegral . (*million)) [0, 5, 30, 55]
    -- Typecast, such as to Double
    pkp_d  = fromIntegral(pkp)
    -- to avoid typo in writing digit
    million   = 1000000

main = print $ map pph pkps

Code above will result a list as below

[500000,10000000,245000000]

Oouuch… the code look ugly. and it lost the intuitive feels.

Am I fail yet ?


What is Next ?

We can get rid of the guard. Consider continue reading [ Haskell - Tax Tariff - Part Three ].

Thank you for visiting.