Satu hal yang membuatnya membingungkan adalah bahwa fungsi "populer" suka bind
dan<*>
berorientasi praksis. Tetapi untuk memahami konsep-konsep itu lebih mudah untuk melihat fungsi-fungsi lain terlebih dahulu. Perlu juga dicatat bahwa monad menonjol karena mereka sedikit overhyped dibandingkan dengan konsep-konsep terhubung lainnya. Jadi saya akan mulai dengan functors saja.
Functors menawarkan fungsi (dalam notasi Haskell) fmap :: (Functor f) => (a -> b) -> f a -> f b
. Dengan kata lain Anda memiliki konteks di f
mana Anda dapat mengangkat suatu fungsi. Seperti yang dapat Anda bayangkan, hampir semuanya adalah functor. Daftar, Mungkin, Either, fungsi, I / O, tuple, parser ... Masing-masing mewakili konteks di mana nilai dapat muncul. Jadi, Anda dapat menulis fungsi yang sangat serbaguna yang bekerja di hampir semua konteks dengan menggunakan fmap
atau varian inline-nya <$>
.
Apa hal lain yang ingin Anda lakukan dengan konteks? Anda mungkin ingin menggabungkan dua konteks. Jadi, Anda mungkin ingin mendapatkan generalisasi dari zip :: [a] -> [b] -> [(a,b)]
contohnya seperti ini: pair :: (Monoidal f) => f a -> f b -> f (a,b)
.
Tetapi karena ini bahkan lebih berguna dalam praktiknya, perpustakaan Haskell malah menawarkan Applicative
, yang merupakan kombinasi dari Functor
dan Monoidal
, Dan juga Unit
, yang hanya menambahkan bahwa Anda benar-benar dapat menempatkan nilai "di dalam" konteks Anda unit
.
Anda dapat menulis fungsi yang sangat umum dengan hanya menyatakan tiga hal ini tentang konteks tempat Anda bekerja.
Monad
hanyalah hal lain yang bisa Anda sebutkan di atas itu. Apa yang tidak saya sebutkan sebelumnya adalah bahwa Anda sudah memiliki dua cara untuk menggabungkan dua konteks: Anda tidak hanya dapat pair
mereka, tetapi Anda juga dapat menumpuknya, misalnya Anda dapat memiliki daftar daftar. Dalam konteks I / O, contoh akan menjadi tindakan I / O yang dapat membaca tindakan I / O lainnya dari file, sehingga Anda akan memiliki tipe FilePath -> IO (IO a)
. Bagaimana kita bisa menghilangkan susunan itu untuk mendapatkan fungsi yang dapat dieksekusi IO a
? Di situlah Monad
s join
masuk, memungkinkan kita untuk menggabungkan dua konteks bertumpuk dari jenis yang sama. Hal yang sama berlaku untuk parser, Mungkin dll. Dan bind
hanya cara yang lebih praktis untuk digunakanjoin
Jadi konteks monadik hanya menawarkan empat hal dan dapat digunakan dengan hampir semua mesin yang dikembangkan untuk I / O, untuk parser, untuk kegagalan dll.