Mengikuti perkembangan toolchain terkini: GHC 9.14.1 sebagai versi LTS pertama dengan dukungan minimal dua tahun, stabilisasi target wasm32wasi dan flag -fsimulate-foreign-errors, jalur rilis stabil 9.12.4, serta ekstensi bahasa seperti GADTs, TypeFamilies, DataKinds dan OverloadedStrings yang menggeser gaya menulis Haskell.

Sampai episode 19, semua kode kita berjalan di atas GHC 9.14.1 — dan belum kita tanya: apa sebenarnya yang baru di versi ini, dan mengapa tim memilihnya? Episode 20 ini menjawab pertanyaan itu, sekaligus mengenalkan ekstensi bahasa yang akan kalian temui di hampir semua proyek Haskell modern.
Mengapa bab ini penting? Karena versi GHC menentukan batas fitur bahasa yang bisa kalian pakai, kecepatan kompilasi, dan jangka waktu dukungan. Di produksi, memilih GHC LTS bukan soal "versi terbaru" — melainkan soal berapa lama tim mendapat patch keamanan tanpa dipaksa upgrade besar.
Pada 19 Desember 2025, GHC 9.14.1 dirilis dengan status bersejarah: ini adalah versi pertama berstatus LTS (Long Term Support). Artinya:
ghc --versionHarus mencetak The Glorious Glasgow Haskell Compilation System, version 9.14.1. Jika kalian masih di 9.8 atau lebih lama, inilah saatnya upgrade — alasan teknisnya di bawah.
Target wasm32wasi — mengkompilasi Haskell ke WebAssembly — menjadi stabil di 9.14. Ini bukan eksperimen lagi: flag --target=wasm32wasi didukung sebagai target resmi, yang kita pakai di episode 18. Implikasi praktisnya besar: kode Haskell bisa dijadikan binary WASM untuk edge runtime dan browser dengan toolchain standar.
ghc --target=wasm32wasi -O2 Main.hs -o app.wasmFlag baru -fsimulate-foreign-errors membantu pengembangan FFI: alih-alih crash process saat error terjadi di kode foreign, GHC mensimulasikan error dan melempar exception Haskell yang bisa ditangkap. Ini membuat debugging interop (episode 18) jauh lebih nyaman:
ghc -fsimulate-foreign-errors Main.hs9.14 membawa perbaikan signifikan pada GHC API (dipakai HLS dan tooling) dan internal compiler — hasilnya: HLS lebih stabil, error type checker lebih informatif, dan kompilasi lebih dapat diprediksi. Bagi kalian sebagai pengguna, efek yang paling terasa adalah editor experience yang lebih mulus dan error yang lebih mudah dibaca.
Memahami peta rilis GHC membantu memilih versi untuk proyek:
| Jalur | Versi | Status |
|---|---|---|
| LTS | 9.14.1 (19 Des 2025) | Dukungan minimal 2 tahun — pilihan default |
| Stable | 9.12.4 (27 Mar 2026) | Jalur stabil terkini |
| Legacy | 9.10.3, 9.8.4, 9.6.7 | Hanya untuk kompatibilitas lama |
Aturan praktis 2026:
Tip
Selalu cek dukungan GHC di build-depends kalian. Sejak 9.14 menjadi baseline, beberapa paket mulai mencantumkan base >= 4.20 atau setara — jika error "cannot build" saat upgrade, biasanya ini alasannya, dan solusinya adalah meng-update dependensi ke versi yang mendukung baseline baru.
Standar bahasa adalah Haskell 2010 — stabil dan konservatif. Inovasi hidup di ekstensi GHC yang diaktifkan per-file dengan pragma. Empat yang paling sering kalian jumpai:
GADTs (Generalized Algebraic Data Types) memungkinkan konstruktor menyandang tipe berbeda:
{-# LANGUAGE GADTs #-}
data Expr a where
Num :: Int -> Expr Int
Bool :: Bool -> Expr Bool
Add :: Expr Int -> Expr Int -> Expr IntSekarang Add hanya menerima Expr Int — compiler tahu bahwa Add (Bool True) (Num 1) mustahil. Tipe menjadi lebih presisi daripada ADT biasa.
TypeFamilies memetakan tipe ke tipe — "fungsi" yang berjalan di compile time:
{-# LANGUAGE TypeFamilies #-}
type family HasKey k where
HasKey (k, v) = v
type instance HasKey (String, Int) = IntType families menjadi dasar dari banyak library modern — termasuk pilihan backend database di Persistent (episode 15).
DataKinds mengangkat nilai data menjadi tipe, membuka pintu pemrograman di level tipe:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
data Ukuran = Kecil | Besar
data Kotak (s :: Ukuran) where
KotakKecil :: Int -> Kotak 'Kecil
KotakBesar :: Int -> Kotak 'Besar'Kecil (dengan petik) adalah nilai Kecil yang diangkat menjadi tipe. Ini fondasi untuk API yang membedakan state pada level tipe — semakin dekat dengan "illegal states unrepresentable" dari episode 17.
OverloadedStrings membuat literal string bisa menjadi String, Text, ByteString, atau tipe lain yang punya instance IsString:
{-# LANGUAGE OverloadedStrings #-}
import Data.Text (Text)
pesan :: Text
pesan = "ini langsung bertipe Text"Tanpa ekstensi ini, literal "..." selalu String dan harus dikonversi manual. Hampir semua proyek modern mengaktifkannya (kalian sudah melihatnya di episode 13).
Daripada menaruh pragma di tiap file, deklarasi ekstensi global di file .cabal (atau default-extensions di proyek) menjaga konsistensi:
library
hs-source-dirs: src
exposed-modules: MyApp
build-depends: base
default-extensions:
OverloadedStrings
DataKinds
GADTsWarning
Ekstensi adalah pedang bermata dua: OverloadedStrings dan DataKinds aman dan banyak dipakai, tetapi ekstensi agresif seperti FlexibleInstances yang tidak perlu bisa membuat kode tidak terbaca dan sulit dimigrasi. Aktifkan hanya yang dibutuhkan — tahan godaan meng-copy daftar ekstensi dari template besar.
build-depends lebih dulu.{-# LANGUAGE X #-} hilang di file.default-extensions pada yang benar-benar dipakai semua modul.Inti yang harus dibawa pulang:
-fsimulate-foreign-errors, perbaikan GHC API/compiler..cabal via default-extensions.Di episode 21 selanjutnya kita akan membahas performance & optimization — strictness analysis dan unlifted types, menghindari space leak dari akumulasi lazy, profiling dengan cabal build --enable-profiling dan +RTS -p, heap profile untuk menemukan kebocoran memori, serta benchmark dengan Criterion. Sampai jumpa di episode 21!