Apakah ada konsep sesuatu seperti functor co-aplikatif duduk di antara comonads dan functors?

17

Monad apa pun juga merupakan fungsi aplikasi dan fungsi aplikasi apa pun adalah fungsi. Juga, comonad apa pun adalah functor. Apakah ada konsep yang sama antara comonads dan functors, sesuatu seperti functor co-aplikatif, dan apa propertinya?

FunctorsFunctorsFungsional yang berlaku???MonadComonads

Pembaruan: Saya juga tertarik dengan kemungkinan penggunaan konsep semacam itu.

Petr Pudlák
sumber
Apakah Anda yakin tidak mencari Comonads -> ??? -> Pejabat?
josiah
1
@ Yosia Tidak, sejauh yang saya tahu, comonads adalah functors , bukan cofunctors.
Petr Pudlák
1
Bukankah membagi potongan yang hilang itu?
Gus

Jawaban:

15

Pertama-tama:

Monad apa pun juga merupakan fungsi aplikasi dan fungsi aplikasi apa pun adalah fungsi.

Ini benar dalam konteks Haskell, tetapi (membaca Applicativesebagai "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 Applicativedengan 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 Applicativemenjelaskan 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 Monadini bisa dibilang artefak dari batasan implisit pada Applicativemenyebabkan 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 pD 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:CCHaihal CDCHaihalDHaihalHSebuahskHaihalApplicative

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 Applicativejika 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 .HSebuahskHaihalnewtype Op b a = Op (a -> b)HSebuahskbSebuahHSebuahskHaihalOp b aHSebuahsk

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:HSebuahskApplicative

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 copureakan menghasilkan comonad (dengan asumsi hukum puas), tentu saja. Tapi tidak ada hubungan yang jelas antara - apa coappun 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 duplicatedan coziptidak 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 Applicativeuntuk 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.HSebuahskHaihalb <~ acontracurry :: (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.HSebuahskCoApplicative

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.

CA McCann
sumber
Membandingkan jawaban Anda dengan cstheory.stackexchange.com/a/22302/989 , mengejutkan bahwa Anda tidak menggandakan jumlah produk menjadi dua. Tentu saja, Anda benar bahwa Hask tidak memiliki jumlah kategori; tetapi jika Anda ingin membatasi ke kategori total program (seperti di Agda), mari kita berpura-pura Set untuk saat ini, masalah itu hilang. (Saya tidak mengatakan Set ^ op bersifat monoid tertutup, tetapi saya menduga apa yang saya katakan menyiratkannya).
Blaisorblade
8

Dalam posting ini di SO saya menemukan jawaban yang menarik - penentu fungsi . Jika kita ganti ()dengan Void, (,)dengan Either dan membalikkan panah, kita mendapatkan:

class Functor f => Decisive f where
    nogood :: f Void -> Void
    orwell :: f (Either s t) -> Either (f s) (f t)

Posting blog juga memberikan beberapa undang-undang yang mematuhi fungsi.

Dan, setiap orang Comonadjuga Decisive:

instance Comonad c => Decisive c where
    nogood = counit
    orwell story = case counit story of
                     Left s  -> fmap (either id (const s)) story
                     Right t -> fmap (either (const t) id) story 

Jadi functors yang tepat cocok di antara functors dan comonads, seperti halnya functors aplikatif yang cocok antara functors dan monads.

Petr Pudlák
sumber
6

McBride dan Patterson (Bagian 7) menunjukkan bahwa functor aplikatif, juga dikenal sebagai idiom, adalah functor monoid longgar yang kuat . Anda mencari functor monoid koloid yang kuat juga dikenal sebagai functor monoidal oplax yang kuat . Seperti disebutkan dalam komentar, sebuah oplax monoidal functor adalah lax monoidal functor antara kategori yang berlawanan, yang akhirnya menjadi versi comonoidal dari lax monoidal functor.

Gambar diagram, balikkan panah!

Saya harus meluangkan sedikit waktu untuk mengerjakan perincian untuk melihat mana itu, dan menerjemahkannya menjadi gagasan pemrograman fungsional.

Dave Clarke
sumber
Untuk beberapa alasan istilah standar tampaknya "oplax monoidal functor". Idenya adalah functor loid monoid antara kategori yang berlawanan, yang akhirnya menjadi versi comonoid dari lact monoidal functor. Menggunakan "colax comonoidal" bisa berlebihan atau setara dengan "lax monoidal".
CA McCann
Saya overdid "co" -ing. Saya akan memperbaiki jawaban saya.
Dave Clarke