Membedah arsitektur toolchain Haskell dari kode sumber hingga binary: cara GHC mengkompilasi ke native code dengan backend LLVM dan dukungan WASM, peran GHCi sebagai REPL, serta komponen ekosistem seperti ghc, ghci, runghc, cabal, stack, HLS dan Prelude beserta alur kerja compile-evaluate-print di balik layar.

Setelah di episode 1 kita memahami mengapa Haskell ada — empat pilar desainnya dan penggunanya di industri — pada episode ini kita membedah bagaimana toolchain Haskell bekerja dari kode sumber hingga program berjalan. Memahami arsitektur ini penting karena hampir semua masalah yang kalian temui sepanjang series berakar di sini: kenapa kompilasi lambat, kenapa HLS butuh versi GHC yang sama, kenapa cabal berbeda dari stack, dan apa sebenarnya yang dieksekusi saat main berjalan.
GHC (Glasgow Haskell Compiler) adalah kompiler Haskell yang paling banyak dipakai, dan menjadi wajah de facto bahasa ini. Alurnya secara garis besar:
Tahapan yang perlu kalian pahami:
.hs dan membangun sintaks tree. Error sintaks muncul di sini.Mengapa ada beberapa backend? Karena setiap target punya trade-off: native backend default cepat untuk build sehari-hari, backend LLVM menghasilkan kode yang kadang lebih optimal di workload numerik, dan target WASM membuka jalan menjalankan Haskell di browser atau edge runtime (dibahas di episode 18).
ghc -O2 -o hello Main.hsFlag -O2 mengaktifkan optimasi penuh; untuk development, -O0 (default) membuat build lebih cepat.
GHCi adalah REPL (Read-Eval-Print Loop) interaktif Haskell. Ini adalah best friend kalian untuk mencoba ekspresi tanpa build:
$ ghci
ghci> 2 + 3 * 4
14
ghci> let double x = x * 2
ghci> double 21
42
ghci> :t map
map :: (a -> b) -> [a] -> [b]
ghci> :q
Leaving GHCi.let untuk mendefinisikan fungsi di sesi, :t untuk menanyakan tipe sebuah ekspresi, dan :q untuk keluar. Sepanjang series kita akan sering memakai GHCi sebagai lab — khususnya perintah :t, :i, dan :set +s yang dibahas di episode 10.
| Komponen | Fungsi |
|---|---|
ghc | Kompiler — mengubah .hs menjadi binary native/WASM |
ghci | REPL interaktif untuk eksperimen dan debugging |
runghc / runhaskell | Menjalankan file .hs langsung tanpa build step |
cabal | Build tool & package manager (Hackage) |
stack | Build tool dengan snapshot reproducible (Stackage) |
hls | Haskell Language Server — IntelliSense untuk editor |
Prelude | Standard library default yang selalu di-import |
Prelude adalah kumpulan fungsi dan tipe dasar yang otomatis tersedia di setiap modul — seperti +, map, filter, length, print, tipe Int, Bool, String, dan seterusnya. Kalian tidak perlu import apa pun untuk memakainya. Inilah sebabnya contoh di episode 0 (addOne, double) langsung berjalan tanpa import.
main :: IO ()
main = print (map (*2) [1,2,3])map (*2) [1,2,3] menghasilkan [2,4,6] dan print mencetaknya ke layar — semua dari Prelude.
runghc menafsirkan file .hs secara langsung, cocok untuk script cepat dan contoh di series ini. Untuk produksi, kalian selalu mengkompilasi dengan ghc atau lewat cabal untuk mendapat binary yang dioptimasi dan terisolasi dependensinya:
runghc Main.hs # cepat, untuk development
ghc -O2 -o app Main.hs # hasil binary native
./appKetika kalian menjalankan file Haskell, urutannya selalu sama:
main :: IO ()
main = putStrLn "Hello, Haskell!"main :: IO () berarti "aksi main adalah aksi IO yang menghasilkan nilai kosong (). Program yang berinteraksi dengan dunia luar harus bermuara di main. Sisi kiri :: mendeklarasikan tipe; detailnya akan kita bedah di episode 5, dan apa itu IO di episode 11.
Tip
Aturan praktis memahami arsitektur GHC: sumber .hs -> type checker (bug terbanyak tertangkap di sini) -> Core -> code generator -> binary. Ketika build error membingungkan, tanyakan dulu "di fase mana ini terjadi" — error tipe sering terlihat seperti masalah lain, tapi lokasinya hampir selalu di type checker.
Kalian akan melihat dua nama build tool sepanjang series ini. Secara singkat:
| Aspek | cabal | stack |
|---|---|---|
| Sumber paket | Hackage (bebas versi) | Stackage snapshot (terkurasi) |
| Reproducibility | via cabal.project.freeze | via resolver LTS |
| Kemudahan pemula | sedang | tinggi |
| Kontrol versi | maksimal | dibatasi snapshot |
Kita bedah keduanya secara mendalam di episode 9, termasuk cara memilih untuk proyek kalian.
Pada episode 2 ini, kalian telah memahami bagaimana toolchain Haskell bekerja dari sumber hingga eksekusi.
Inti yang harus dibawa pulang:
:t untuk tipe, let untuk definisi, :q untuk keluar.ghc, ghci, runghc, cabal, stack, HLS, dan Prelude yang selalu tersedia.main :: IO (); interaksi dunia luar dikurung di IO.Di episode 3 selanjutnya kita akan melakukan instalasi & hello world — memastikan toolchain benar-benar berfungsi dengan menulis program pertama, menjalankannya via runghc dan cabal run, serta mengenal alur kerja build paling dasar yang akan dipakai sepanjang series. Sampai jumpa di episode 3!