Buset dah, siapa bilang belajar Haskell tuh bikin pala ngebul dan cuma buat ilmuwan doang? Sini pada ngumpul! Buat lu para developer yang pengen nyicipin keajaiban Functional Programming alias Logika Murni, lu lagi mendarat di artikel yang paling tepat. Kali ini, kita kaga bakal bahas teori ngebosenin yang bikin mata sepet. Kita bakal langsung terjun ngoding ngebangun sistem Aplikasi Kasir beneran dari nol!
Kaga tanggung-tanggung, kita bakal sulap bahasa Haskell yang katanya kaku ini jadi aplikasi Point of Sale (POS) kelas berat buat PT Putra Armssy Perkasa. Mulai dari bikin logika ngitung duit murni, nerima input kasir interaktif yang anti-typo, sistem diskon otomatis, ngerangkum barang belanjaan, sampe fitur dewa: nge-generate struk digital berformat HTML dan nyatet log pembukuan otomatis ke file text. Sruput dulu kopinya bosku, tarik napas panjang, karena kita bakal cicil materinya per babak biar otak lu tetep adem. Gasss!
Kita bakal bangun aplikasi kasir buat PT Putra Armssy Perkasa. Karena kita mainnya di Haskell, lo wajib hukumnya buang jauh-jauh dah tuh kebiasaan Object-Oriented (OOP) yang ribet. Di sini semuanya Logika Murni (Purely Functional). Nggak ada tuh yang namanya variabel yang bisa diubah-ubah sesuka hati di tengah jalan (immutable coy!), semuanya serba fungsi dan presisi.
Babak 1: Bikin Fondasi Data & Logika Murni Ngitung Duit
Di Babak pertama ini, kita bakal bikin struktur data keranjangnya dulu. Anggap aja kita lagi nyiapin etalase buat produk-produk PT Putra Armssy Perkasa.
1. Definisikan Tipe Data Barang
Di Haskell, kita pake data buat bikin struktur. Kita bikin tipe data Barang yang isinya ada ID, Nama, dan Harga. Buat file baru namanya Kasir.hs, terus ketik script ini:
-- Kasir.hs
module Kasir where
-- Bikin tipe data buat representasi barang di toko lu
data Barang = Barang {
idBarang :: Int,
namaBarang :: String,
harga :: Double
} deriving (Show, Eq)
-- Kita bikin list stok barang PT Putra Armssy Perkasa
-- Nah, ini pure function yang nge-return list konstan (nggak bisa diubah-ubah)
stokToko :: [Barang]
stokToko = [
Barang 1 "Sabun Cuci Piring (Formulasi MES & Texapon)" 15500.0,
Barang 2 "Bahan Baku LABS 1 Liter" 25000.0,
Barang 3 "Parfum Laundry Premium" 45000.0
]
2. Bikin Logika Murni (Pure Function) Kasir
Nah, inti dari functional programming tuh ada di sini. Kita bikin fungsi yang tugasnya cuma satu: nerima list barang (keranjang), terus ngeluarin total harganya. Nggak ada efek samping (side-effects), nggak ada baca-tulis ke database dulu. Bener-bener murni matematika. Tambahin script ini di bawahnya:
-- Fungsi murni buat ngitung total belanjaan
-- Dia nerima list [Barang] dan nge-return angka Double
hitungTotal :: [Barang] -> Double
hitungTotal keranjang = sum (map harga keranjang)
-- Fungsi buat nyari barang berdasarkan ID
-- Pake 'filter' buat nyaring data dari stokToko
cariBarang :: Int -> [Barang] -> [Barang]
cariBarang idDicari stok = filter (\b -> idBarang b == idDicari) stok
map harga keranjang itu ibaratnya lu ngambil label harga dari masing-masing barang di keranjang, terus sum itu buat ngejumlahin semua harga yang udah lu ambil tadi. Simpel, padat, dan elegant banget kan?
3. Tampilan Hasil (Test Drive di GHCi)
Sekarang kita tes jalanin script-nya di terminal/command prompt lu pake GHCi (REPL-nya Haskell). Begini nih hasil tampilannya pas dieksekusi:
> ghci Kasir.hs
[1 of 1] Compiling Kasir ( Kasir.hs, interpreted )
Ok, one module loaded.
*Kasir> -- Ceritanya ada pelanggan beli Sabun Cuci Piring (ID 1) sama Parfum (ID 3)
*Kasir> let keranjangBelanja = (cariBarang 1 stokToko) ++ (cariBarang 3 stokToko)
*Kasir> -- Coba kita liat isi keranjangnya
*Kasir> keranjangBelanja
[Barang {idBarang = 1, namaBarang = "Sabun Cuci Piring (Formulasi MES & Texapon)", harga = 15500.0},Barang {idBarang = 3, namaBarang = "Parfum Laundry Premium", harga = 45000.0}]
*Kasir> -- Sekarang kita suruh program ngitung total bayarnya
*Kasir> hitungTotal keranjangBelanja
60500.0
Tuh, mantap kan? Logika murninya udah jalan mulus. Totalnya langsung dapet 60500.0 tanpa perlu lo bikin looping for/while yang ribet kayak di bahasa pemrograman lain.
Babak 2: I/O Monad, Kasir Mulai Interaktif
Lanjut lagi nih coy! Tarik napas dulu, sruput kopinya. Di Babak 2 ini, kita bakal bikin aplikasi kasir PT Putra Armssy Perkasa bener-bener idup dan bisa diajak ngobrol lewat terminal. Di Haskell, buat ngambil input dari keyboard (ngetik ID barang) dan nampilin teks ke layar, kita butuh jembatan yang namanya IO Monad. Anggap aja IO ini kayak satpam yang ngatur keluar-masuknya data dari dunia luar ke dalem program kita.
1. Bikin Fungsi Interaktif Pake 'do' Block
Kita bakal bikin fungsi tanyaBarang yang bakal nanya ID barang terus-terusan sampe kasirnya ngetik angka 0. Ini pake konsep Rekursi buat gantiin looping kayak while atau for.
-- Kasir.hs (Lanjutan)
import System.IO (hFlush, stdout)
-- ... (Kode Barang, stokToko, hitungTotal, cariBarang tetep ada di atas ya) ...
-- Fungsi buat nerima input kasir berulang kali sampe kelar
tanyaBarang :: IO [Barang]
tanyaBarang = do
putStr "Masukin ID Barang (Ketik 0 kalo udah beres): "
hFlush stdout -- Biar teksnya langsung nongol ga nunggu enter
input <- getLine -- Ngambil ketikan dari kasir
let idInput = read input :: Int -- Ngubah teks jadi angka (Integer)
if idInput == 0
then return [] -- Kalo 0, balikin list kosong (keranjang ditutup)
else do
let barangKetemu = cariBarang idInput stokToko
if null barangKetemu
then do
putStrLn "Buset, ID kaga nemu coy! Cek lagi dah list-nya."
tanyaBarang -- Looping lagi, manggil dirinya sendiri
else do
let barang = head barangKetemu
putStrLn $ "=> Masuk keranjang: " ++ namaBarang barang ++ " - Rp " ++ show (harga barang)
-- Lanjut nanya barang berikutnya (Rekursi)
barangSelanjutnya <- tanyaBarang
-- Gabungin barang yang barusan sama barang-barang selanjutnya
return (barang : barangSelanjutnya)
-- Fungsi utama buat jalanin programnya dari awal
main :: IO ()
main = do
putStrLn "======================================"
putStrLn " KASIR PT PUTRA ARMSSY PERKASA "
putStrLn "======================================"
keranjang <- tanyaBarang -- Mulai proses nanya barang
putStrLn "--------------------------------------"
putStrLn "Daftar Belanjaan Lu:"
-- Pake mapM_ buat nge-print setiap barang di keranjang satu-satu
mapM_ (\b -> putStrLn $ "- " ++ namaBarang b ++ " (Rp " ++ show (harga b) ++ ")") keranjang
putStrLn "--------------------------------------"
let total = hitungTotal keranjang
putStrLn $ "TOTAL BAYAR: Rp " ++ show total
putStrLn "======================================"
putStrLn "Makasih bosku, salam cuan!"
-
input <- getLine: Ini cara kita nyedot teks yang diketik di terminal.-
return: Di Haskell, return itu BUKAN buat berhentiin fungsi. return itu bungkus data murni lu biar bisa masuk ke dalem box IO.-
mapM_: Ini cara fungsional buat nge-looping list untuk tujuan nge-print.
2. Tampilan Hasil (Jalanin Programnya)
> runhaskell Kasir.hs
======================================
KASIR PT PUTRA ARMSSY PERKASA
======================================
Masukin ID Barang (Ketik 0 kalo udah beres): 1
=> Masuk keranjang: Sabun Cuci Piring (Formulasi MES & Texapon) - Rp 15500.0
Masukin ID Barang (Ketik 0 kalo udah beres): 3
=> Masuk keranjang: Parfum Laundry Premium - Rp 45000.0
Masukin ID Barang (Ketik 0 kalo udah beres): 99
Buset, ID kaga nemu coy! Cek lagi dah list-nya.
Masukin ID Barang (Ketik 0 kalo udah beres): 2
=> Masuk keranjang: Bahan Baku LABS 1 Liter - Rp 25000.0
Masukin ID Barang (Ketik 0 kalo udah beres): 0
--------------------------------------
Daftar Belanjaan Lu:
- Sabun Cuci Piring (Formulasi MES & Texapon) (Rp 15500.0)
- Parfum Laundry Premium (Rp 45000.0)
- Bahan Baku LABS 1 Liter (Rp 25000.0)
--------------------------------------
TOTAL BAYAR: Rp 85500.0
======================================
Makasih bosku, salam cuan!
Gila, udah mirip sistem POS beneran kan? Semuanya jalan mulus pake rekursi, tanpa ada satu pun variabel yang kita ubah-ubah nilainya (mutated).
Babak 3: Sistem Pembayaran & Kembalian
Sikat miring! Kita lanjut ke Babak 3 nih coy. Masa iya orang belanja kaga bayar? Kita bakal bikin sistem buat nerima duit dari pelanggan, ngitung kembalian, plus nyetak struk belanja yang rapi.
1. Bikin Fungsi Murni Buat Ngitung Kembalian
-- Fungsi murni ngitung kembalian. Cuma ngurangin doang, kaga ada efek samping.
hitungKembalian :: Double -> Double -> Double
hitungKembalian total bayar = bayar - total
2. Bikin Aksi I/O Buat Nodong Duit Pelanggan
-- Fungsi IO buat nerima pembayaran
prosesPembayaran :: Double -> IO Double
prosesPembayaran totalBelanja = do
putStr "Masukin Duit Pelanggan: Rp "
hFlush stdout
inputDuit <- getLine
let duit = read inputDuit :: Double
if duit < totalBelanja
then do
putStrLn "Yaelah bos, duitnya kurang nih! Tambahin ngapa."
prosesPembayaran totalBelanja -- Duit kurang? Looping nanya lagi!
else do
putStrLn "Duit diterima, mantap!"
return duit
3. Rombak Fungsi main Buat Cetak Struk
main :: IO ()
main = do
putStrLn "======================================"
putStrLn " KASIR PT PUTRA ARMSSY PERKASA "
putStrLn "======================================"
keranjang <- tanyaBarang
if null keranjang
then putStrLn "Kaga ada yang dibeli, balik kanan dah!"
else do
putStrLn "\n--------------------------------------"
putStrLn "RINCIAN BELANJAAN:"
mapM_ (\b -> putStrLn $ "- " ++ namaBarang b ++ " (Rp " ++ show (harga b) ++ ")") keranjang
let total = hitungTotal keranjang
putStrLn "--------------------------------------"
putStrLn $ "TOTAL KESELURUHAN : Rp " ++ show total
putStrLn "--------------------------------------\n"
-- Manggil fungsi bayar
duitPelanggan <- prosesPembayaran total
-- Ngitung kembalian pake fungsi murni
let kembalian = hitungKembalian total duitPelanggan
-- Cetak Struk Akhir
putStrLn "\n======================================"
putStrLn " STRUK LUNAS "
putStrLn "======================================"
putStrLn $ "TOTAL BELANJA : Rp " ++ show total
putStrLn $ "TUNAI : Rp " ++ show duitPelanggan
putStrLn $ "KEMBALIAN : Rp " ++ show kembalian
putStrLn "======================================"
putStrLn " Makasih ye, besok mampir lagi dah! "
putStrLn "======================================"
4. Tampilan Hasil Akhir (Test Drive)
> runhaskell Kasir.hs
======================================
KASIR PT PUTRA ARMSSY PERKASA
======================================
Masukin ID Barang (Ketik 0 kalo udah beres): 2
=> Masuk keranjang: Bahan Baku LABS 1 Liter - Rp 25000.0
Masukin ID Barang (Ketik 0 kalo udah beres): 3
=> Masuk keranjang: Parfum Laundry Premium - Rp 45000.0
Masukin ID Barang (Ketik 0 kalo udah beres): 0
--------------------------------------
RINCIAN BELANJAAN:
- Bahan Baku LABS 1 Liter (Rp 25000.0)
- Parfum Laundry Premium (Rp 45000.0)
--------------------------------------
TOTAL KESELURUHAN : Rp 70000.0
--------------------------------------
Masukin Duit Pelanggan: Rp 50000
Yaelah bos, duitnya kurang nih! Tambahin ngapa.
Masukin Duit Pelanggan: Rp 100000
Duit diterima, mantap!
======================================
STRUK LUNAS
======================================
TOTAL BELANJA : Rp 70000.0
TUNAI : Rp 100000.0
KEMBALIAN : Rp 30000.0
======================================
Makasih ye, besok mampir lagi dah!
======================================
Ini udah jadi core alias mesin utamanya.
Babak 4: Nyiptain Struk Digital (HTML)
Sebelonnya kita udah sukses bikin sistem bayar-bayaran. Tapi hari gini, masa aplikasi kasir kaga bisa nyimpen data struknya? Nah, biar makin greget, di Babak 4 ini kita bakal bikin aplikasi kasir lu otomatis nyiptain file HTML (Struk Digital) setiap kali transaksi kelar.
1. Bikin Fungsi Murni Buat Ngerakit HTML
-- Fungsi murni buat ngubah data barang jadi tag <li> HTML
bikinListHTML :: [Barang] -> String
bikinListHTML keranjang = concatMap (\b -> "<li>" ++ namaBarang b ++ " - <b>Rp " ++ show (harga b) ++ "</b></li>\n") keranjang
-- Fungsi murni buat ngerakit full halaman HTML
rakitStrukHTML :: [Barang] -> Double -> Double -> Double -> String
rakitStrukHTML keranjang total bayar kembalian =
"<!DOCTYPE html>\n" ++
"<html>\n" ++
"<head>\n" ++
" <title>Struk PT Putra Armssy Perkasa</title>\n" ++
" <style>\n" ++
" body { font-family: monospace; max-width: 400px; margin: auto; padding: 20px; border: 1px dashed #000; }\n" ++
" h2 { text-align: center; border-bottom: 2px solid #000; padding-bottom: 10px; }\n" ++
" ul { list-style-type: none; padding: 0; }\n" ++
" li { padding: 5px 0; border-bottom: 1px dotted #ccc; }\n" ++
" .total { font-weight: bold; font-size: 1.2em; text-align: right; margin-top: 15px; }\n" ++
" </style>\n" ++
"</head>\n" ++
"<body>\n" ++
" <h2>PT PUTRA ARMSSY PERKASA</h2>\n" ++
" <p>Rincian Belanjaan:</p>\n" ++
" <ul>\n" ++
bikinListHTML keranjang ++
" </ul>\n" ++
" <div class='total'>\n" ++
" <p>TOTAL: Rp " ++ show total ++ "</p>\n" ++
" <p>TUNAI: Rp " ++ show bayar ++ "</p>\n" ++
" <p>KEMBALIAN: Rp " ++ show kembalian ++ "</p>\n" ++
" </div>\n" ++
" <p style='text-align: center;'>Makasih ye, besok mampir lagi dah!</p>\n" ++
"</body>\n" ++
"</html>"
2. Update Fungsi main Buat Nulis ke File
Tambahin di bagian paling bawah main lu:
-- Cetak Struk Akhir di Terminal (Tetep ada)
-- ... (Kode sebelumnya) ...
-- PROSES BIKIN FILE HTML (Baru nih di Babak 4!)
putStrLn "\n[Sistem] Lagi nge-generate struk digital..."
let isiHTML = rakitStrukHTML keranjang total duitPelanggan kembalian
-- writeFile itu aksi I/O, dia nerima nama file dan string isinya
writeFile "struk_transaksi.html" isiHTML
putStrLn "[Sistem] Mantap! Struk berhasil disimpen ke 'struk_transaksi.html'"
3. Tampilan Hasil (Test Drive)
======================================
STRUK LUNAS
======================================
TOTAL BELANJA : Rp 70000.0
TUNAI : Rp 100000.0
KEMBALIAN : Rp 30000.0
======================================
Makasih ye, besok mampir lagi dah!
======================================
[Sistem] Lagi nge-generate struk digital...
[Sistem] Mantap! Struk berhasil disimpen ke 'struk_transaksi.html'
File ini udah langsung fast-render kaga pake loading-loadingan karena HTML murni tanpa script aneh-aneh!
Babak 5: Sistem Diskon Otomatis Pakai Guards
Di Babak 5 ini kita bakal nambahin Sistem Diskon Otomatis. Kita bakal kenalan sama fitur sakti namanya Guards (|). Tetep murni, tetep elegan.
1. Bikin Fungsi Murni Ngitung Diskon Pake Guards
-- Fungsi murni ngitung diskon pake Guards (|)
hitungDiskon :: Double -> Double
hitungDiskon totalAwal
| totalAwal >= 100000 = totalAwal * 0.10 -- Diskon 10%
| totalAwal >= 50000 = totalAwal * 0.05 -- Diskon 5%
| otherwise = 0.0 -- Sisanya 0
-- Fungsi murni buat ngitung total yang udah dipotong diskon
hitungTotalBersih :: Double -> Double -> Double
hitungTotalBersih totalAwal diskon = totalAwal - diskon
2. Rombak Fungsi HTML Buat Nampilin Diskon
-- Sekarang nerima totalAwal, diskon, bayar, dan kembalian
rakitStrukHTML :: [Barang] -> Double -> Double -> Double -> Double -> String
rakitStrukHTML keranjang totalAwal diskon bayar kembalian =
"<!DOCTYPE html>\n" ++
"<html>\n" ++
-- ... (bagian head sama style tetep sama kayak Babak 4) ...
"<body>\n" ++
" <h2>PT PUTRA ARMSSY PERKASA</h2>\n" ++
" <p>Rincian Belanjaan:</p>\n" ++
" <ul>\n" ++
bikinListHTML keranjang ++
" </ul>\n" ++
" <div class='total'>\n" ++
" <p>SUBTOTAL: Rp " ++ show totalAwal ++ "</p>\n" ++
" <p style='color: red;'>DISKON: -Rp " ++ show diskon ++ "</p>\n" ++
" <p>TOTAL BAYAR: Rp " ++ show (totalAwal - diskon) ++ "</p>\n" ++
" <p>TUNAI: Rp " ++ show bayar ++ "</p>\n" ++
" <p>KEMBALIAN: Rp " ++ show kembalian ++ "</p>\n" ++
" </div>\n" ++
" <p style='text-align: center;'>Makasih ye, besok mampir lagi dah!</p>\n" ++
"</body>\n" ++
"</html>"
3. Eksekusi di Fungsi main & Tampilan Test Drive
--------------------------------------
SUBTOTAL : Rp 115000.0
DISKON : Rp 11500.0
TOTAL BERSIH : Rp 103500.0
--------------------------------------
Masukin Duit Pelanggan: Rp 150000
Duit diterima, mantap!
======================================
STRUK LUNAS
======================================
TOTAL BELANJA : Rp 103500.0
TUNAI : Rp 150000.0
KEMBALIAN : Rp 46500.0
======================================
Cakep bener! Aplikasinya udah pinter ngasih diskon otomatis tanpa repot.
Babak 6: Grouping & Counting (Biar Kertas Irit)
Kalo ada pelanggan borong 10 jerigen "Bahan Baku LABS", masa di struknya kecetak 10 baris ke bawah? Di Babak 6 ini, kita bakal ngerangkum barang yang sama jadi satu baris pake kuantitas (misal: Bahan Baku LABS x10) pake Tuple.
1. Rombak Dikit Tipe Data Barang
-- Tambahin 'Ord' di deriving biar bisa disortir
data Barang = Barang {
idBarang :: Int,
namaBarang :: String,
harga :: Double
} deriving (Show, Eq, Ord)
2. Import Tools Baru dan Bikin Logika Rekap
import System.IO (hFlush, stdout)
import Data.List (group, sort) -- Baru nih! Buat ngurutin & ngelompokkin
-- Fungsi murni buat ngerekap keranjang -> [(Barang, Int)]
rekapKeranjang :: [Barang] -> [(Barang, Int)]
rekapKeranjang keranjang =
let keranjangUrut = sort keranjang
keranjangNgelompok = group keranjangUrut
in map (\g -> (head g, length g)) keranjangNgelompok
3. Update Fungsi Cetak HTML & Eksekusi
bikinListHTMLRekap :: [(Barang, Int)] -> String
bikinListHTMLRekap rekap = concatMap formatBaris rekap
where
formatBaris (b, qty) =
let subharga = harga b * fromIntegral qty
in "<li>" ++ namaBarang b ++ " <b>x" ++ show qty ++ "</b> - <b>Rp " ++ show subharga ++ "</b></li>\n"
Hasil Test Drive-nya bakal kayak gini bos:
--------------------------------------
RINCIAN BELANJAAN:
- Bahan Baku LABS 1 Liter x2 (Rp 50000.0)
- Parfum Laundry Premium x3 (Rp 135000.0)
--------------------------------------
SUBTOTAL : Rp 185000.0
DISKON : Rp 18500.0
TOTAL BERSIH : Rp 166500.0
--------------------------------------
Babak 7: Anti-Crash System Pake Maybe
Kalo udah sampe sini, logic functional lu udah keasah tajem banget. Tapi bayangin kasir lu disuruh masukin ID barang (angka), eh jarinya kepeleset ngetik huruf "A". Program lu bakal nge-crash! Nah, kita pake konsep sakti namanya Maybe.
import Text.Read (readMaybe) -- Baru nih! Buat baca input dengan aman
-- Fungsi nerima input kasir (Anti-Crash Version)
tanyaBarang :: IO [Barang]
tanyaBarang = do
putStr "Masukin ID Barang (Ketik 0 kalo udah beres): "
hFlush stdout
input <- getLine
-- Kita cek nih, inputnya bisa diubah ke Int apa kaga
case readMaybe input :: Maybe Int of
Nothing -> do
putStrLn "Buset bos! Masukin ID pake angka ngapa, jangan huruf! Ulang yak."
tanyaBarang
Just idInput -> do
if idInput == 0
then return []
else do
let barangKetemu = cariBarang idInput stokToko
if null barangKetemu
then do
putStrLn "ID kaga nemu coy! Cek lagi dah list-nya."
tanyaBarang
else do
let barang = head barangKetemu
putStrLn $ "=> Masuk keranjang: " ++ namaBarang barang ++ " - Rp " ++ show (harga barang)
barangSelanjutnya <- tanyaBarang
return (barang : barangSelanjutnya)
case readMaybe inputDuit :: Maybe Double of .... Sekarang program lu bener-bener solid dan tahan banting dari *typo* kasir.
Babak 8: Pembukuan Otomatis (Log Harian)
Transaksi jalan terus, tapi pas tutup toko... jeng jeng, lu kaga tau hari ini dapet duit berapa. Di Babak 8 ini, kita bakal bikin Pembukuan Otomatis (Log Harian) pake appendFile.
1. Bikin Fungsi Murni Buat Format Laporan
-- Tambahin "\n" di belakang biar tiap nambah data baru otomatis ganti baris
formatLaporanBukuKas :: Double -> Double -> Double -> String
formatLaporanBukuKas total bayar kembalian =
"TRANSAKSI SUKSES | Pendapatan: Rp " ++ show total ++ " | Diterima: Rp " ++ show bayar ++ " | Kembalian: Rp " ++ show kembalian ++ "\n"
2. Update Fungsi main Buat Nyatet Pembukuan
-- Pake appendFile biar data ditambahin di baris paling bawah, BUKAN ditimpa!
putStrLn "[Sistem] Nyatet pemasukan ke buku kas..."
let barisLaporan = formatLaporanBukuKas totalBersih duitPelanggan kembalian
appendFile "buku_kas_harian.txt" barisLaporan
putStrLn "[Sistem] Beres bos! Pemasukan udah aman dicatet di 'buku_kas_harian.txt'"
Kalo lu buka file buku_kas_harian.txt, isinya bakal rapih kayak gini:
TRANSAKSI SUKSES | Pendapatan: Rp 15500.0 | Diterima: Rp 20000.0 | Kembalian: Rp 4500.0
TRANSAKSI SUKSES | Pendapatan: Rp 90000.0 | Diterima: Rp 100000.0 | Kembalian: Rp 10000.0
FAQ Spesial: Aplikasi Kasir Haskell PT Putra Armssy Perkasa
Q: Bang, kenapa sih harus pake Haskell? Kan bahasa lain kayak Python atau PHP lebih gampang?
A: Nah, ini dia. Haskell itu emang kurva belajarnya lumayan bikin pala nyut-nyutan di awal. Tapi keunggulannya ada di Keamanan dan Presisi. Karena kaga ada state yang bisa diubah sembarangan (imutabilitas), lu kaga bakal nemuin bug aneh macem race conditions. Buat ngurusin duit (aplikasi kasir), lu butuh kepastian matematis.
Q: Ini hasil output HTML struknya enteng kaga Bang kalo diliat di HP?
A: Enteng banget parah! Kita ngerakit HTML-nya murni cuma pake tag dasar macem <ul>, <li>, sama CSS dikit di <style>. Kaga ada JavaScript aneh-aneh yang bikin forced reflow. Jadi struk ini sifatnya ultra-lightweight.
Q: Bang, kalo besok-besok gua mau nambahin produk baru, gua harus bongkar kodenya mulu?
A: Buat versi yang kita bikin sampe Babak 8 ini, iyak bener, lu harus nambahin manual di fungsi stokToko. Kalo lu mau upgrade aplikasinya ke next level, lu bisa pake fungsi IO buat ngebaca data stok dari file .csv atau .json otomatis.
Q: Performa aplikasinya kenceng kaga nih kalo dipake kasir beneran?
A: Wah, jangan ngeremehin Haskell bos! Buat performa maksimal lu bisa kompilasi kode lu pake perintah ghc -O2 Kasir.hs. Itu bakal nge-generate file executable yang udah dioptimasi tingkat dewa. Performanya deket-deket sama C atau C++ karena dia langsung dieksekusi sama hardware.
Lu sekarang udah megang PAKEMNYA gimana caranya ngebangun aplikasi pake gaya Functional Programming murni. Kodenya ringkas, aman, dan yang pasti... keren abis buat dipamerin! Salam cuan buat bisnis!