Table of Content

These are Tax Rate in Haskell related articles.

Haskell - Tax Tariff - Part OneHaskell - Tax Tariff - Part Two

Haskell - Tax Tariff - Part Three

Haskell - Tax Tariff - Part Four

The temptation of the challenge is so high. How about last attempt to simplify the code, based on the original calculation method from the first article?

### Rewrite The Guard

Consider going back to our previous nice code, with guard, but reversed order.

```
import Data.Foldable
-- taxable incomes
pkps :: [Int]
pkps = [0, 50*10^6, 250*10^6, 500*10^6, 10^9]
-- income tax using progressive tariff
pph :: Int -> Int
pph pkp = round $ pph_recursive $ fromIntegral pkp
where
[t1, t2, t3, t4] = map (* 10^6) [0, 50, 250, 500]
[p1, p2, p3, p4] = [0.05, 0.15, 0.25, 0.30]
pph_recursive pkp_real
| pkp_real > t4 = (pkp_real - t4) * p4 + pph_recursive t4
| pkp_real > t3 = (pkp_real - t3) * p3 + pph_recursive t3
| pkp_real > t2 = (pkp_real - t2) * p2 + pph_recursive t2
| pkp_real > t1 = (pkp_real - t1) * p1 + pph_recursive t1
| otherwise = 0
main = forM_ pkps (print . pph)
```

Code above will show each calculation as below

```
0
2500000
32500000
95000000
245000000
```

It is simple, clean, and easy to understand.

Can you see the pattern with that guard above?

### Alternate Recursive

Consider using list comprehension, and built the recursive based on pattern above.

```
import Data.Foldable
-- taxable incomes
pkps :: [Int]
pkps = [0, 50*10^6, 250*10^6, 500*10^6, 10^9]
-- income tax using progressive tariff
pph :: Int -> Int
pph pkp = round $ pph_recursive $ fromIntegral pkp
where
pph_recursive 0 = 0
pph_recursive pkp_real = (pkp_real - tm) * p + pph_recursive(tm)
where
-- [(tingkat, persentase)]
reff = [(0, 0.05), (50, 0.15), (250, 0.25), (500, 0.30)]
indices = [ i | (i, (t, p)) <- zip [0..] reff, pkp_real > t * (10^6)]
(t, p) = (reff !! last indices)
tm = t * (10^6)
main = forM_ pkps (print . pph)
```

It turned out, that we need nested `where`

clause.
And I still need pattern matching to stop the recursion.

Code above will show each result the same as previous output.

It is not simple. And not easy to understand.

### Further Attempt

Consider using lambda as our last resort.

```
import Data.Foldable
-- taxable incomes
pkps :: [Int]
pkps = [0, 50*10^6, 250*10^6, 500*10^6, 10^9]
-- income tax using progressive tariff
pph :: Int -> Int
pph pkp = round $ pph_recursive $ fromIntegral pkp
where
-- [(tingkat, persentase)]
reff = [(0, 5), (50, 15), (250, 25), (500, 30)]
tarrifs = [ (t*(10^6), (p/100)) | (t, p) <- reff]
pph_recursive 0 = 0
pph_recursive pkp_real =
(\(t, p) -> (pkp_real - t) * p + pph_recursive(t)) tariff
where
indices = [ i | (i, (t, p)) <- zip [0..] tarrifs, pkp_real > t]
tariff = tarrifs !! last indices
main = mapM_ (print . pph) pkps
```

Code above will show each result the same as previous output.

It is getting cryptic. And simply garbage. A sad ending in the middle of midnight.

### Conclusion

I fail

However, examining this many codes to solve one issue, is good experience anyway. I found that Haskell has a very nice syntax. Thus, I won’t regret this mess.

The first calculation code in this series article is the coolest. Consider continue going back reading [ Haskell - Tax Tariff - Part One ].

Thank you for visiting. We shall meet again. Farewell.