Ada banyak pembicaraan tentang monad hari ini. Saya telah membaca beberapa artikel / posting blog, tetapi saya tidak bisa cukup jauh dengan contoh-contoh mereka untuk memahami konsep sepenuhnya. Alasannya adalah bahwa monad adalah konsep bahasa fungsional, dan dengan demikian contohnya adalah dalam bahasa yang belum pernah saya gunakan (karena saya belum menggunakan bahasa fungsional secara mendalam). Saya tidak dapat memahami sintaksis cukup dalam untuk mengikuti artikel sepenuhnya ... tapi saya bisa mengatakan ada sesuatu yang layak dipahami di sana.
Namun, saya tahu C # cukup baik, termasuk ekspresi lambda dan fitur fungsional lainnya. Saya tahu C # hanya memiliki subset fitur fungsional, dan jadi mungkin monad tidak dapat diekspresikan dalam C #.
Namun, mungkinkah untuk menyampaikan konsep tersebut? Setidaknya saya harap begitu. Mungkin Anda dapat menyajikan contoh C # sebagai sebuah yayasan, dan kemudian menggambarkan apa yang ingin dilakukan oleh pengembang C # dari sana tetapi tidak bisa karena bahasa tersebut tidak memiliki fitur pemrograman fungsional. Ini akan fantastis, karena akan menyampaikan maksud dan manfaat monad. Jadi, inilah pertanyaan saya: Apa penjelasan terbaik yang bisa Anda berikan tentang monad kepada pengembang C # 3?
Terima kasih!
(EDIT: Ngomong-ngomong, saya tahu setidaknya sudah ada 3 pertanyaan "apa itu monad" di SO. Namun, saya menghadapi masalah yang sama dengan mereka ... jadi pertanyaan ini sangat dibutuhkan, karena C # -developer fokus. Terima kasih.)
Jawaban:
Sebagian besar yang Anda lakukan dalam pemrograman sepanjang hari adalah menggabungkan beberapa fungsi bersama untuk membangun fungsi yang lebih besar darinya. Biasanya Anda tidak hanya memiliki fungsi di kotak peralatan Anda, tetapi juga hal-hal lain seperti operator, penugasan variabel, dan sejenisnya, tetapi umumnya program Anda menggabungkan banyak "perhitungan" dengan perhitungan yang lebih besar yang akan digabungkan bersama lebih lanjut.
Monad adalah beberapa cara untuk melakukan ini "menggabungkan perhitungan".
Biasanya "operator" Anda yang paling dasar untuk menggabungkan dua perhitungan bersama adalah
;
:Ketika Anda mengatakan ini, Anda maksudkan "lakukan dulu
a
, baru lakukanb
". Hasilnyaa; b
pada dasarnya lagi perhitungan yang dapat digabungkan dengan lebih banyak barang. Ini adalah monad sederhana, ini adalah cara menyisir perhitungan kecil ke yang lebih besar. The;
mengatakan "melakukan hal yang di sebelah kiri, kemudian melakukan hal yang di sebelah kanan".Hal lain yang dapat dilihat sebagai monad dalam bahasa berorientasi objek adalah
.
. Seringkali Anda menemukan hal-hal seperti ini:Pada
.
dasarnya berarti "mengevaluasi perhitungan di sebelah kiri, dan kemudian memanggil metode di sebelah kanan pada hasil itu". Ini adalah cara lain untuk menggabungkan fungsi / komputasi bersama, sedikit lebih rumit daripada;
. Dan konsep chaining things bersama.
adalah monad, karena itu adalah cara menggabungkan dua komputasi bersama-sama ke komputasi baru.Monad lain yang cukup umum, yang tidak memiliki sintaks khusus, adalah pola ini:
Nilai balik -1 menunjukkan kegagalan, tetapi tidak ada cara nyata untuk mengabstraksi pengecekan kesalahan ini, bahkan jika Anda memiliki banyak panggilan API yang perlu Anda gabungkan dengan cara ini. Ini pada dasarnya hanyalah monad lain yang menggabungkan panggilan fungsi dengan aturan "jika fungsi di sebelah kiri mengembalikan -1, lakukan return -1 sendiri, jika tidak panggil fungsi di sebelah kanan". Jika kami memiliki operator
>>=
yang melakukan hal ini, kami cukup menulis:Itu akan membuat hal-hal lebih mudah dibaca dan membantu untuk mengabstraksi cara khusus kami menggabungkan fungsi, sehingga kita tidak perlu mengulangi diri kita lagi dan lagi.
Dan ada banyak lagi cara untuk menggabungkan fungsi / perhitungan yang berguna sebagai pola umum dan dapat diabstraksi dalam monad, memungkinkan pengguna monad untuk menulis kode yang jauh lebih ringkas dan jelas, karena semua pembukuan dan pengelolaan fungsi yang digunakan dilakukan di monad.
Sebagai contoh, hal di atas
>>=
dapat diperluas untuk "melakukan pemeriksaan kesalahan dan kemudian memanggil sisi kanan pada soket yang kita dapatkan sebagai input", sehingga kita tidak perlu secara eksplisit menentukansocket
banyak kali:Definisi formal sedikit lebih rumit karena Anda harus khawatir tentang cara mendapatkan hasil dari satu fungsi sebagai input ke yang berikutnya, jika fungsi itu membutuhkan input itu dan karena Anda ingin memastikan bahwa fungsi yang Anda gabungkan cocok dengan cara Anda mencoba menggabungkan mereka di monad Anda. Tetapi konsep dasarnya adalah hanya Anda memformalkan berbagai cara untuk menggabungkan fungsi bersama.
sumber
;
contoh Anda : Objek / tipe data apa yang;
dipetakan? (PikirkanList
petaT
untukList<T>
) Bagaimana;
peta morfisme / fungsi antara objek / tipe data? Apapure
,join
,bind
untuk;
?Sudah setahun sejak saya memposting pertanyaan ini. Setelah mempostingnya, saya menyelidiki Haskell selama beberapa bulan. Saya sangat menikmatinya, tetapi saya mengesampingkannya ketika saya siap untuk mempelajari Monads. Saya kembali bekerja dan fokus pada teknologi yang dibutuhkan proyek saya.
Dan tadi malam, saya datang dan membaca kembali tanggapan-tanggapan ini. Yang paling penting , saya membaca kembali contoh C # spesifik dalam komentar teks dari video Brian Beckman yang disebutkan seseorang di atas . Itu sangat jelas dan menerangi sehingga saya memutuskan untuk mempostingnya langsung di sini.
Karena komentar ini, tidak hanya aku merasa seperti aku mengerti persis apa yang monads yang ... Saya menyadari saya sudah benar-benar menulis beberapa hal di C # yang merupakan monads ... atau setidaknya sangat dekat, dan berusaha untuk memecahkan masalah yang sama.
Jadi, inilah komentar - ini semua kutipan langsung dari komentar di sini oleh sylvan :
sumber
Monad pada dasarnya merupakan pemrosesan yang ditangguhkan. Jika Anda mencoba menulis kode yang memiliki efek samping (mis. I / O) dalam bahasa yang tidak mengizinkannya, dan hanya memungkinkan perhitungan murni, satu penghindaran adalah mengatakan, "Oke, saya tahu Anda tidak akan melakukan efek samping untuk saya, tetapi bisakah Anda menghitung apa yang akan terjadi jika Anda melakukannya? "
Ini semacam curang.
Sekarang, penjelasan itu akan membantu Anda memahami maksud gambaran besar dari monad, tetapi iblis ada dalam rinciannya. Bagaimana tepatnya cara Anda menghitung konsekuensi? Terkadang, itu tidak cantik.
Cara terbaik untuk memberikan ikhtisar tentang bagaimana seseorang yang terbiasa dengan pemrograman imperatif adalah dengan mengatakan bahwa ia menempatkan Anda dalam DSL di mana operasi yang terlihat secara sintaksis seperti apa yang Anda gunakan di luar monad digunakan sebagai gantinya untuk membangun fungsi yang akan dilakukan apa yang Anda inginkan jika Anda dapat (misalnya) menulis ke file output. Hampir (tetapi tidak benar-benar) seolah-olah Anda sedang membangun kode dalam sebuah string untuk kemudian dievaluasi.
sumber
Maybe
danEither e
) dan manajemen negara (State s
,ST s
) menyerang saya sebagai contoh khusus "Tolong hitung apa yang akan terjadi jika Anda melakukan [efek samping untuk saya]". Contoh lain adalah nondeterminisme ([]
).Saya yakin pengguna lain akan memposting secara mendalam, tetapi saya menemukan video ini membantu sampai batas tertentu, tetapi saya akan mengatakan bahwa saya masih tidak sampai kefasihan dengan konsep sedemikian rupa sehingga saya bisa (atau harus) mulai menyelesaikan masalah secara intuitif dengan Monads.
sumber
Anda dapat menganggap monad sebagai C #
interface
yang harus diimplementasikan oleh kelas . Ini adalah jawaban pragmatis yang mengabaikan semua matematika teoretis kategori di balik mengapa Anda ingin memilih untuk memiliki deklarasi ini di antarmuka Anda dan mengabaikan semua alasan mengapa Anda ingin memiliki monad dalam bahasa yang mencoba menghindari efek samping, tapi saya menemukan ini sebagai awal yang baik sebagai seseorang yang mengerti (C #) antarmuka.sumber
Lihat jawaban saya untuk "Apa itu monad?"
Itu dimulai dengan contoh yang memotivasi, bekerja melalui contoh itu, mengambil contoh dari monad, dan secara resmi mendefinisikan "monad".
Ini mengasumsikan tidak memiliki pengetahuan pemrograman fungsional dan menggunakan pseudocode dengan
function(argument) := expression
sintaks dengan ekspresi sesederhana mungkin.Program C # ini adalah implementasi dari pseudocode monad. (Untuk referensi:
M
adalah konstruktor tipe,feed
adalah operasi "bind", danwrap
merupakan operasi "return".)sumber