Jika kita membandingkan jenisnya
(<*>) :: Applicative a => a (s -> t) -> a s -> a t
(>>=) :: Monad m => m s -> (s -> m t) -> m t
kami mendapatkan petunjuk tentang apa yang memisahkan kedua konsep tersebut. Bahwa (s -> m t)dalam tipe (>>=)menunjukkan bahwa nilai dalam sdapat menentukan perilaku komputasi dalam m t. Monads memungkinkan interferensi antara nilai dan lapisan komputasi. The (<*>)Operator memungkinkan tidak ada gangguan seperti: fungsi dan argumen perhitungan tidak bergantung pada nilai-nilai. Ini benar-benar menggigit. Membandingkan
miffy :: Monad m => m Bool -> m x -> m x -> m x
miffy mb mt mf = do
b <- mb
if b then mt else mf
yang menggunakan hasil dari beberapa efek untuk memutuskan antara dua perhitungan (mis. meluncurkan rudal dan menandatangani gencatan senjata), sedangkan
iffy :: Applicative a => a Bool -> a x -> a x -> a x
iffy ab at af = pure cond <*> ab <*> at <*> af where
cond b t f = if b then t else f
yang menggunakan nilai abuntuk memilih di antara nilai-nilai dari dua perhitungan atdan af, setelah melakukan keduanya, mungkin menghasilkan efek yang tragis.
Versi monadik pada dasarnya bergantung pada kekuatan ekstra (>>=)untuk memilih penghitungan dari suatu nilai, dan itu bisa jadi penting. Namun, mendukung kekuatan tersebut membuat monad sulit untuk dibuat. Jika kita mencoba membangun 'ikatan ganda'
(>>>>==) :: (Monad m, Monad n) => m (n s) -> (s -> m (n t)) -> m (n t)
mns >>>>== f = mns >>-{-m-} \ ns -> let nmnt = ns >>= (return . f) in ???
kita sampai sejauh ini, tapi sekarang lapisan kita semua campur aduk. Kami memiliki n (m (n t)), jadi kami harus menyingkirkan bagian luarnya n. Seperti yang dikatakan Alexandre C, kita bisa melakukannya jika kita punya yang cocok
swap :: n (m t) -> m (n t)
untuk mengubah ke ndalam dan joinke yang lain n.
'Penerapan ganda' yang lebih lemah jauh lebih mudah untuk didefinisikan
(<<**>>) :: (Applicative a, Applicative b) => a (b (s -> t)) -> a (b s) -> a (b t)
abf <<**>> abs = pure (<*>) <*> abf <*> abs
karena tidak ada interferensi antar lapisan.
Sejalan dengan itu, ada baiknya untuk mengenali kapan Anda benar-benar membutuhkan kekuatan ekstra Monads, dan kapan Anda bisa lolos dengan struktur komputasi kaku yang Applicativemendukung.
Perhatikan, ngomong-ngomong, meskipun menyusun monad itu sulit, itu mungkin lebih dari yang Anda butuhkan. Jenis tersebut m (n v)menunjukkan komputasi dengan m-efek, kemudian komputasi dengan n-efek ke v-nilai, di mana m-efek selesai sebelum n-efek dimulai (karena itu diperlukan swap). Jika Anda hanya ingin mmenyisipkan -efek dengan n-efek, maka komposisi mungkin terlalu banyak untuk ditanyakan!