Apa itu Comonad dan bagaimana mereka berguna?

16

Baru-baru ini saya telah membuang pengetahuan saya tentang cara kerja Monads. Saya juga telah diperkenalkan dengan konsep 'Comonad' , yang digambarkan sebagai dua kebalikan dari monad . Namun, saya tidak mungkin membungkus kepala saya di sekitarnya.

Untuk memahami Monads, saya membuat analogi sendiri untuk diri saya sendiri:

Monads dapat dilihat sebagai 'cetak biru untuk membangun ban berjalan ekspresi'.

Untuk mendefinisikan Monad baru (sistem conveyor-belt jenis baru), Anda perlu mendefinisikan:

  1. Cara untuk meletakkan sesuatu di sabuk konveyor, misalnya 'memulai' sabuk konveyor. (Dikenal sebagai unitatau return)
  2. Cara menghubungkan mesin (ekspresi) yang akan menjadi bagian dari ban berjalan ke ban berjalan. (Dikenal sebagai joinatau bindatau >>=).

(Ada operasi ketiga yang mengambil sabuk konveyor saat ini, membuang isinya dan memulai sabuk konveyor baru yang dikenal sebagai >>, tetapi sangat jarang digunakan.)

Agar mesin dan konveyor dapat bekerja dengan baik bersama-sama, Anda harus memastikan bahwa:

  1. Jika Anda meletakkan sesuatu di sabuk konveyor dan melewatkannya melalui mesin, hasilnya harus sama seperti ketika Anda melewatkannya melalui mesin secara manual. (Identitas Kiri)
  2. Jika Anda ingin meletakkan sabuk konveyor di antara sabuk konveyor yang sudah ada, Anda tidak boleh berakhir dengan sabuk konveyor yang memiliki sabuk konveyor di bagian atas, melainkan sabuk konveyor yang lebih panjang dan tunggal. (Identitas Benar)
  3. Seharusnya tidak masalah untuk output jika Anda secara manual menggunakan mesin A, dan kemudian meneruskan hasilnya melalui BC yang terhubung dengan conveyor, atau jika Anda menggunakan AB yang terhubung dengan conveyor dan kemudian meneruskan hasilnya secara manual melalui C. Dengan kata lain: ((a >> = b) >> = c) harus sama dengan (a >> = (b >> = c)) (Asosiatif)

Belt conveyor yang paling sederhana adalah yang hanya mengambil input dan selalu melanjutkan ke ekspresi berikutnya. Inilah yang dimaksud dengan 'pipeline'.

Kemungkinan lain, adalah hanya membiarkannya melalui mesin berikutnya jika beberapa kondisi terpenuhi untuk nilai. Ini berarti bahwa jika pada beberapa ekspresi di antaranya, nilainya berubah menjadi sesuatu yang tidak lagi diizinkan, maka sisa ekspresi akan dilewati. Inilah yang dilakukan monad 'Mungkin' di Haskell.

Anda juga dapat melakukan aturan salin / ubah kondisional lainnya pada nilai sebelum atau setelah Anda menyerahkannya ke mesin. Contoh: Parsers (Di sini, jika ekspresi mengembalikan hasil 'kegagalan', nilai dari sebelum ekspresi digunakan sebagai output).

Tentu saja analoginya tidak sempurna, tapi saya harap ini memberikan gambaran yang baik tentang bagaimana monad bekerja.

Namun, saya memiliki banyak kesulitan untuk mengubah analogi ini di kepalanya untuk memahami Comonads. Saya tahu dari sejumlah kecil informasi yang saya temukan di internet yang didefinisikan oleh Comonad:

  • extract, Yang merupakan semacam kebalikan dari return, yang, dibutuhkan nilai keluar dari Comonad.
  • duplicate, Yang merupakan jenis kebalikan dari join, yaitu, ia menciptakan dua Comonads dari satu.

Tetapi bagaimana Comonad dapat dipakai jika kita hanya dapat mengekstrak dari mereka atau menduplikasi mereka? Dan bagaimana mereka bisa digunakan? Saya telah melihat proyek yang sangat luar biasa ini dan pembicaraan tentang hal itu (yang sayangnya saya mengerti sangat sedikit), tetapi saya tidak yakin bagian mana dari fungsi yang disediakan oleh Comonad sebenarnya.

Apa itu Comonad? Apa manfaatnya? Bagaimana mereka bisa digunakan? Apakah bisa dimakan?

Qqwy
sumber
2
"Bagaimana Comonad bisa dipakai jika kita hanya bisa mengekstrak dari mereka atau menggandakannya?" - Saya akan menjawab pertanyaan Anda dengan pertanyaan: bagaimana Monad dapat dikonsumsi jika Anda hanya dapat mengangkat nilai ke dalamnya dan mengurutkan perhitungan?
Benjamin Hodgson
1
"Mesin di ujung sabuk konveyor" (samping: Saya tidak menemukan analogi yang sangat membantu ketika berbicara tentang monad) dari IOmonad adalah sistem runtime Haskell, yang digunakan main. Tentu unsafePerformIOsaja ada. Jika Anda ingin menganggap Maybemonad memiliki "mesin di ujung ban berjalan" yang dapat Anda gunakan maybe.
Benjamin Hodgson
1
Tetapi, membalikkan penjelasan Anda, ketika Anda ingin menghasilkan nilai comonadic pada awal rangkaian cobindaplikasi, harus ada beberapa fungsi yang melakukan sesuatu yang berguna dengan representasi internal comonad Anda.
Benjamin Hodgson
2
contoh spesifik comonad atau monad jelas dapat memiliki fungsionalitas lebih dari yang dibutuhkan hanya untuk mengimplementasikan typeclasses
jk.
2
Bukannya ini akan membantu jika Anda tidak mendekati pertanyaan ini dari kategori-teoretis / matematika, tetapi saya ingin menunjukkan bahwa comonad bukan kebalikannya melainkan dual monad.
Jörg W Mittag

Jawaban:

11

Comonad adalah, seperti halnya monad, struktur matematika dalam teori kategori. Co-prefix sangat umum di sana untuk menunjukkan "invers" seperti yang Anda katakan (meskipun saya tidak berpikir ahli matematika murni setuju pada pilihan kata).

Dalam teori kategori ada categories, yang secara singkat menempatkan koleksi objects(dari jenis atau sifat apa pun, struktur internal tidak relevan) dan beberapa di arrowsantara objek-objek ini. Untuk sesuatu yang menjadi kategori, panah harus mengikuti beberapa hukum (kiri / kanan-identitas dan asosiatif), tetapi itu tidak terlalu penting di sini.

Sekarang, teori kategori sangat abstrak / sulit untuk grok dan luas. Dibutuhkan banyak waktu untuk membahas semuanya (dan saya belum mempelajarinya secara formal, saya hanya tahu beberapa dasar), tetapi ada gagasan yang digunakan yang disebut a dual. Pada dasarnya, untuk setiap kategori Anda dapat membuat sebuah opposite categorydengan hanya melakukan hal yang sama tetapi "membalikkan semua panah". Ini adalah definisi yang sangat naif tetapi sulit untuk meringkasnya. Dual sesuatu dalam kategori C pada dasarnya adalah hal yang sama dalam kategori yang berlawanan C_op (belum pusing?)

Lagi pula, jika Anda memiliki monad atas beberapa kategori (dan kategori misalnya bisa menjadi kategori di mana objek adalah tipe dalam beberapa bahasa pemrograman dan panah adalah fungsi antara tipe), maka comonad pada dasarnya adalah hal yang sama, hanya Anda Sudah membalik semua panah (seperti membalikkan tanda tangan fungsi dalam kasus ini).

Yang lebih "hands-on" description (meskipun tangan-tidak SUPER) dapat ditemukan dalam ini diskusi antara Erik Meijer dan Brian Beckman di mana mereka membahas gagasan dualitas dan bagaimana Erik pergi tentang "membalikkan panah" untuk IEnumerable<T>di C # saat menciptakan kerangka kerja reaktif dan IObservable<T>(yang sejauh yang saya tahu, dan saya senang bisa dikoreksi, pada dasarnya adalah contoh daftar comonad).

Contoh praktis lain dari comonads yang disebutkan dalam video adalah Task<T>ketik .NET, di mana Task<U> ContinueWith<U>(Func<Task<T>, U>)akan menjadi ganda bind(atau SelectManyseperti yang disebut dalam C #)

sara
sumber