### Preface

Goal: Progressive Tax Rate Formula in Haskell

I found a good income taxes case to be written in Haskell. Yes it is the progressive tax tariff formula in functional programming.

Following regulation in my country the tarrifs is defined as below:

```
Progressively
0 until 50 million: 5%
> 50 until 250 million: 15%
> 250 until 500 million: 25%
> 500 million : 30%
```

Cumulative equation in math can be described as below:

#### Spreadsheet Version

I have wrote an article in my local language, about making progressive tax tariff formula in spreadsheet:

#### Challenge

I found that the Excel function is very nice. So short that it only takes this one line:

`=max( ({5;15;25;30}%*$PPh) - {0;5;30;55}*10^6 )`

Can I do this shorter in Haskell ?

Short answer: No!

But I found that Haskell can solve this issue very nicely.

#### Meanwhile

It is after midnight here, so tired after attending a night class in campus. But I have promise myself to finish this article.

### Simple Example

#### Calculation

With simple calculation using math the tarrif is as below:

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

All in Rupiah currency.

#### Matplotlib Chart

With matplotlib we can plot above equation to this chart below:

Actually, this chart above is not very helpful. In order to have better understanding, wen need infographic below.

#### Infographic Chart

### Haskell Code

#### Typecast

Consider start writing code, with very simple typecast from Real to Integer.

```
-- taxable income
pkp :: Float
pkp = 1000000000
main = do
print $ round pkp
```

This will show

`1000000000`

You can use either `Float`

type.
If you need better precision, you may consider `Double`

type.

#### Using Function

Be lazy. Learn Haskell!

The next step is write down what I did in paper step by step, in function. Since Haskell is lazy and pure functional, the order of the function does not matter.

```
-- taxable income
pkp :: Double
pkp = 1000000000
-- income tax using progressive tariff
(t1, t2, t3) = (50000000, 250000000, 500000000)
pph :: Double -> Double
pph pkp = if pkp <= t1
then pph_t1 pkp
else pph_t2 pkp
pph_t1 :: Double -> Double
pph_t1 pkp = pkp * 0.05
pph_t2 :: Double -> Double
pph_t2 pkp = if pkp <= t2
then (pkp - t1) * 0.15 + pph_t1(t1)
else pph_t3 pkp
pph_t3 :: Double -> Double
pph_t3 pkp = if pkp <= t3
then (pkp - t2) * 0.25 + pph_t2(t2)
else pph_t4 pkp
pph_t4 :: Double -> Double
pph_t4 pkp = (pkp - t3) * 0.30 + pph_t3(t3)
main = do
print $ round $ pph pkp
```

Code above will result as below

`245000000`

Actually the code above does not looks good. We can rephrase the sentence above to better code poetry.

#### Using Guard and Recursive Function

Guard combined with Recursive Function, can resolve the function very nicely.

```
-- taxable income
pkp :: Double
pkp = 1000000000
-- income tax using progressive tariff
pph :: Double -> Double
pph pkp = pkpr pkp
where
(t1, t2, t3) = (50000000, 250000000, 500000000)
pkpr pkp
| pkp <= t1 = pkp * 0.05
| pkp <= t2 = (pkp - t1) * 0.15 + pph t1
| pkp <= t3 = (pkp - t2) * 0.25 + pph t2
| otherwise = (pkp - t3) * 0.30 + pph t3
main = do
print $ round (pph pkp)
```

When we no longer use recursive controlled by `pkp <= t1`

.
Otherwise, we will have endlees loop.

Guard can control the tail of of recursive.

Now our last issue, calculated value in my country should be in integer, rather than real number.

#### Integer Value

How do we round it inside function?

We should typecast the taxable income in the first place.

```
-- taxable income
pkp :: Int
pkp = 10^9
-- income tax using progressive tariff
pph :: Int -> Int
pph pkp = round $ pph_recursive $ fromIntegral pkp
where
[t1, t2, t3] = map (* 10^6) [50, 250, 500]
pph_recursive pkp_real = pkp_guard pkp_real
pkp_guard pkp
| pkp <= t1 = pkp * 0.05
| pkp <= t2 = (pkp - t1) * 0.15 + pph_rec t1
| pkp <= t3 = (pkp - t2) * 0.25 + pph_rec t2
| otherwise = (pkp - t3) * 0.30 + pph_rec t3
main = print $ pph pkp
```

Notice that we are no longer need to use round in `main do`

clause.
And we can even omit `do`

in oneliner fashioned.

The code is very nice and intuitive.

### What is Next ?

How about the challenge above ?

There are other way to do this calculation. Consider continue reading [ Haskell - Tax Tariff - Part Two ].

Thank you for visiting.