9 poin oleh bboydart91 2026-02-08 | 2 komentar | Bagikan ke WhatsApp

Isi

  • Menjelaskan dengan kode TypeScript proses yang berawal dari dua masalah yang tidak bisa diselesaikan hanya dengan map pada functor (masalah fungsi yang terkurung di dalam container, dan masalah konteks yang bertumpuk saat komposisi) hingga sampai pada applicative functor dan monad
  • Dimulai dari latar belakang ketika Eugenio Moggi pada 1988 memodelkan program bukan sebagai A → B, melainkan A → T(B)
  • Membahas struktur flatMap = map + join dan tiga hukum untuk menggunakannya dengan aman (asosiatif, identitas kiri, identitas kanan)
  • Menjelaskan mengapa monad disebut "objek monoid dalam kategori endofunctor" dengan membandingkannya dengan monoid penjumlahan bilangan bulat
  • Juga menyebutkan alasan Promise bekerja secara monadik tetapi bukan monad matematis dalam arti yang ketat

Keterbatasan functor: hal-hal yang tidak bisa dilakukan dengan map

  • Jika fungsi yang sudah di-curried diterapkan dengan map, hasilnya membuat fungsi terkurung di dalam container seperti Maybe<(b: number) => number>
    • map hanya bisa menerima fungsi di luar container, sehingga tidak ada cara menerapkan fungsi yang terkurung di dalamnya ke nilai lain
  • Jika dua fungsi yang mengembalikan functor dikomposisikan, konteks akan bertumpuk seperti Maybe<Maybe>
    • Semakin banyak tahap, semakin bertumpuk tanpa batas menjadi Maybe<Maybe<Maybe<...>>>

Applicative functor: menerapkan fungsi di dalam container

  • Dengan operasi apply, fungsi yang terkurung di dalam container bisa diterapkan ke nilai dari container lain
    • apply: T<(A → B)> → T<A> → T<B>
  • Dengan operasi pure, nilai murni dimasukkan ke dalam container
  • Keterbatasannya: container mana saja yang akan dikomposisikan harus sudah ditentukan sebelumnya
    • Tidak bisa mengekspresikan dependensi sekuensial dinamis yang menentukan komputasi berikutnya berdasarkan hasil komputasi sebelumnya

Monad: penemuan operasi untuk meratakan tumpukan

  • Operasi join meratakan container ganda T<T<A>> → T<A> menjadi satu lapisan
    • Array.prototype.flat di JavaScript menjalankan peran yang sama
  • Dalam praktik, yang digunakan adalah flatMap, gabungan map + join
    • flatMap: T<A> → (A → T<B>) → T<B>
    • map menerima A → B, sedangkan flatMap menerima A → T<B> sehingga hasilnya tetap satu lapisan

Tiga hukum flatMap

  • Hukum asosiatif: saat meratakan tiga lapisan T(T(T(A))), hasilnya harus sama baik diratakan dari dalam dulu maupun dari luar dulu
    • m.flatMap(f).flatMap(g) === m.flatMap(x => f(x).flatMap(g))
  • Hukum identitas kiri: jika nilai dimasukkan dengan pure lalu langsung di-flatMap, hasilnya sama seperti menerapkan fungsi secara langsung
    • pure(a).flatMap(f) === f(a)
  • Hukum identitas kanan: jika pure diberikan ke flatMap, hasilnya tetap container semula
    • m.flatMap(pure) === m

Mengurai "objek monoid dalam kategori endofunctor"

  • Functor dalam pemrograman adalah endofunctor karena bergerak dari dunia tipe ke dunia tipe
  • Kita bisa membentuk kategori endofunctor yang menjadikan endofunctor itu sendiri sebagai objek
  • Jika dipetakan ke syarat monoid (operasi biner + hukum asosiatif + elemen identitas), hasilnya adalah:
    • operasi biner = join
    • elemen identitas = pure
    • Strukturnya persis berkorespondensi dengan monoid penjumlahan bilangan bulat

Mengapa Promise bukan monad

  • then menangani campuran map dan flatMap tergantung nilai kembalian
  • Keadaan Promise<Promise> tidak diizinkan pada runtime dan langsung digabung menjadi satu lapisan
  • Praktis dan nyaman dalam kerja sehari-hari, tetapi tidak memenuhi hukum monad matematis

2 komentar

 
calofmijuck 2026-02-08

Tolong bahas juga Comonad!

 
bboydart91 2026-02-09

Wah... saya akan memikirkannya dulu wkwkwk