Pertama-tama:
Monad apa pun juga merupakan fungsi aplikasi dan fungsi aplikasi apa pun adalah fungsi.
Ini benar dalam konteks Haskell, tetapi (membaca Applicative
sebagai "lax monoidal functor kuat") tidak secara umum, untuk alasan yang agak sepele bahwa Anda dapat memiliki "aplikator" functors antara kategori monoidal yang berbeda, sedangkan monads (dan comonads) adalah endofunctors .
Selanjutnya, mengidentifikasi Applicative
dengan functor monoid longgar lemah adalah sedikit menyesatkan, karena untuk membenarkan nama (dan jenis tanda tangan (<*>)
) memerlukan functor antara kategori monoid tertutup yang mempertahankan struktur monoid dan hom internal . Hal ini dapat secara masuk akal disebut sebagai "functor monoid tertutup lemah", kecuali bahwa functor antara kategori tertutup monoid yang mempertahankan salah satu properti mempertahankan yang lain dengan cara yang jelas . Karena Applicative
menjelaskan hanya endofunctor pada Hask yang melestarikan struktur monoid, instansnya(,)
memperoleh banyak properti secara otomatis, termasuk kekuatannya , yang dengan demikian dapat dielakkan.
Hubungan yang jelas dengan Monad
ini bisa dibilang artefak dari batasan implisit pada Applicative
menyebabkan aspek dari struktur monoid masing-masing bertepatan, suatu kebetulan bahagia yang sayangnya tidak bertahan dualisasi.
Hanya sebagai comonad pada kategori adalah monad di C o p , sebuah oplax monoidal functor C → D adalah longgar monoidal functor C o p → D o p . Tetapi tidak tertutup secara monoid , dan sebuah co- yang tidak menyertakan aplikasi fungsi hampir tidak pantas untuk namanya. Bagaimanapun, hasilnya tidak akan terlalu menarik:CCo hlm C→ DCo hlm→ Do hlmHa s ko hlmApplicative
class (Functor f) => CoMonoidal f where
counit :: f () -> ()
cozip :: f (a, b) -> (f a, f b)
Kita malah bisa membayangkan gagasan "colax closed functor", yang akan terlihat jauh lebih seperti Applicative
jika ada. Sayangnya, sama sekali tidak (menurut sepengetahuan saya) kategori tertutup sama sekali: di sesuai dengan morfisme di , tetapi tidak berfungsi sebagai hom internal di sana - karena panah dibalik, semacam fungsi bersama akan diperlukan sebagai gantinya, yang kami tidak dapat mendefinisikan secara umum untuk .Ha s ko hlmnewtype Op b a = Op (a -> b)
Ha s kb → aHa s ko hlmOp b a
Ha s k
Jika kita hanya berpura-pura bahwa "colax closed functors" ada untuk , dan selanjutnya bekerja dengan cara yang kita harapkan dengan naif, sebuah co- based yang mungkin akan terlihat seperti ini:Ha s kApplicative
class (Functor f) => CoApplicative f where
copure :: f a -> a
coap :: (f a -> f b) -> f (a -> b)
Menambahkan duplicate :: f a -> f (f a)
ke copure
akan menghasilkan comonad (dengan asumsi hukum puas), tentu saja. Tapi tidak ada hubungan yang jelas antara - apa coap
pun itu - dan extend :: (f a -> b) -> f a -> f b
. Membandingkan tipe-tipe itu menjadi jelas bahwa dualisasi terjadi dengan cara yang berbeda: struktur comonoidal yang mendasari duplicate
dan cozip
tidak ada hubungannya dengan satu sama lain atau dengan coap
(yang mungkin tidak masuk akal juga), sedangkan liftA2 (,)
dan (<*>)
adalah setara dan dapat diturunkan dari join
.
Cara lain yang memungkinkan Applicative
untuk melakukan dualisasi, yang lebih sedikit hubungannya dengan comonads, adalah dengan mempertimbangkan fungsi-fungsi monoid yang kontravarian:
class (Contravariant f) => ContraMonoidal f where
contraunit :: f a
contrazip :: f a -> f b -> f (Either a b)
Tetapi ini bertabrakan dengan masalah yang sama seperti di atas, yaitu bahwa bukan kategori tertutup. Jika ya, kita akan memiliki beberapa jenis sehingga kita dapat menulis fungsi seperti dan dan seterusnya yang benar-benar berfungsi seperti yang diharapkan.Ha s ko hlmb <~ a
contracurry :: (Either c b <~ a) -> (c <~ (b <~ a))
contraapply :: b -> Either a (a <~ b)
Jika ingatanku, kendala di sini tidak spesifik untuk Haskell, tetapi lebih muncul dari menjadi cartesian ditutup (tentu saja dengan melambaikan tangan,), properti yang dibagikan dengan kalkulus lambda yang paling diketik, jadi Anda tidak akan terlalu jauh dengan di sebagian besar pengaturan.Ha s kCoApplicative
Namun, dalam kategori tertutup monoid yang lebih ramah terhadap dualisasi, Anda mungkin lebih beruntung. Secara khusus, saya percaya keduanya Kleisli (Cont r)
dan kategorinya yang berlawanan tertutup rapat, sehingga mungkin merupakan konteks yang lebih baik untuk mengeksplorasi ide-ide ini.