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.