Sebuah monad adalah hanya sebuah monoid dalam kategori endofunctors, apa's masalah?

Yang pertama kata berikut ini?

monad adalah hanya sebuah monoid dalam kategori endofunctors, apa's masalah?

Dan yang lebih penting diperhatikan, apakah ini benar dan jika demikian anda bisa memberikan penjelasan (mudah-mudahan salah satu yang dapat dipahami oleh seseorang yang doesn't memiliki banyak Haskell pengalaman)?

Mengomentari pertanyaan (9)
Larutan

Bahwa kata-kata tertentu adalah dengan James Iry, dari-nya yang sangat menghibur Singkat, Lengkap dan Sebagian besar Salah Sejarah Bahasa Pemrograman, di mana ia fictionally atribut ini untuk Philip Wadler.

Kutipan asli dari Saunders Mac Lane dalam Kategori untuk Bekerja Matematika, salah satu dasar teks-teks dari Teori Kategori. Di sini adalah dalam konteks, yang mungkin adalah tempat terbaik untuk belajar persis apa artinya.

Tapi, aku'll mengambil bacokan. Asli kalimat ini:

Semua mengatakan, sebuah monad di X adalah hanya sebuah monoid dalam kategori endofunctors X, dengan produk × diganti dengan komposisi endofunctors dan unit yang ditetapkan oleh identitas endofunctor.

X berikut adalah kategori. Endofunctors yang functors dari kategori itu sendiri (yang biasanya semua `Functor ini sejauh fungsional programmer yang bersangkutan, karena mereka're kebanyakan berurusan dengan hanya satu kategori; kategori dari jenis - tapi saya ngelantur). Tapi anda bisa bayangkan kategori lain yang merupakan kategori "endofunctors pada X". Ini adalah kategori di mana benda-benda yang endofunctors dan morphisms alami transformasi.

Dan orang-orang endofunctors, beberapa dari mereka mungkin monads. Mana yang monads? Persis orang-orang yang monoidal dalam arti tertentu. Bukan ejaan yang tepat pemetaan dari monads untuk monoids (sejak Mac Lane yang jauh lebih baik daripada yang saya bisa berharap untuk), I'll hanya menempatkan definisi masing-masing sisi dengan sisi dan membiarkan anda membandingkan:

Sebuah monoid adalah...

  • Satu set, S
  • Operasi, • : S × S → S
  • Unsur S, e : 1 → S

...memuaskan undang-undang ini:

  • (a • b) • c = a • (b • c), untuk semua a, b dan c di S
  • e • a = a • e = a, untuk semua a di S

A monad adalah...

  • Sebuah endofunctor, T : X → X (di Haskell, jenis konstruktor dari jenis * -> * dengan Functor contoh)
  • Sebuah transformasi alam, μ : T × T → T, dimana × sarana functor komposisi (µ dikenal sebagai bergabung di Haskell)
  • Sebuah transformasi alam, η : I → T, dimana I adalah identitas endofunctor pada X (η dikenal sebagai kembali di Haskell)

...memuaskan undang-undang ini:

  • μ ∘ Tµ = μ ∘ µT
  • μ ∘ Tn = μ ∘ nT = 1 (identitas transformasi alam)

Dengan sedikit menyipitkan mata anda mungkin bisa melihat bahwa kedua definisi tersebut adalah kasus yang sama abstrak.

Komentar (46)

Secara intuitif, saya berpikir bahwa apa yang mewah kosakata matematika katakan adalah bahwa:

Monoid

A monoid adalah sekumpulan objek, dan metode menggabungkan mereka. Dikenal monoids adalah:

  • anda dapat menambahkan nomor
  • anda dapat menggabungkan daftar
  • set anda dapat union

Ada lebih banyak contoh yang kompleks juga.

Lebih lanjut, setiap monoid memiliki identitas, yang adalah bahwa "no-op" elemen yang tidak memiliki efek ketika anda menggabungkan itu dengan sesuatu yang lain:

  • 0 + 7 == 7 + 0 == 7
  • [] ++ [1,2,3] == [1,2,3] ++ [] == [1,2,3]
  • {} union {apel} == {apel} union {} == {apple}

Akhirnya, sebuah monoid harus asosiatif. (anda dapat mengurangi string panjang kombinasi yang tetap anda inginkan, asalkan anda don't mengubah kiri-ke-kanan-urutan benda-benda) Itu adalah OK ((5+3)+1 == 5+(3+1)), tapi pengurangan isn't ((5-3)-1 != 5-(3-1)).

Monad

Sekarang, let's mempertimbangkan jenis khusus dari set dan cara khusus untuk menggabungkan objek.

Benda-benda

Misalkan anda set berisi benda-benda dari jenis khusus: fungsi. Dan fungsi-fungsi ini memiliki sebuah tanda tangan yang menarik: Mereka don't membawa angka ke angka atau string ke string. Sebaliknya, fungsi masing-masing membawa sebuah nomor ke daftar nomor yang di proses dua langkah.

  1. Menghitung 0 atau lebih hasil
  2. Menggabungkan hasil tersebut kepada satu jawaban yang entah bagaimana.

Contoh:

  • 1 -> [1] (hanya membungkus input)
  • 1 -> [] (membuang input, bungkus kehampaan dalam daftar)
  • 1 -> [2] (tambahkan 1 untuk input, dan membungkus hasil)
  • 3 -> [4, 6] (tambahkan 1 untuk input, dan memperbanyak input dengan 2, dan membungkus beberapa hasil)

Menggabungkan Benda-Benda

Juga, cara menggabungkan fungsi-fungsi khusus. Cara sederhana untuk menggabungkan fungsi komposisi: Let's ambil contoh kita di atas, dan menulis masing-masing fungsi dengan dirinya sendiri:

  • 1 -> [1] -> [[1]] (bungkus input, dua kali)
  • 1 -> [] -> [] (membuang input, bungkus kehampaan dalam daftar, dua kali)
  • 1 -> [2] -> [ EH-OH! ] (kita bisa't "tambahkan 1" untuk daftar!")
  • 3 -> [4, 6] -> [ EH-OH! ] (kita bisa't tambahkan 1 daftar!)

Tanpa terlalu banyak ke jenis teori, intinya adalah bahwa anda dapat menggabungkan dua bilangan bulat untuk mendapatkan bilangan bulat, tetapi anda dapat't selalu menulis dua fungsi dan mendapatkan fungsi dari jenis yang sama. (Fungsi dengan mengetik a -> sebuah akan menulis, tetapi a-> [a] tidak't.)

Jadi, let's menentukan cara yang berbeda untuk menggabungkan fungsi. Ketika kita menggabungkan dua fungsi ini, kita don't ingin "ganda-bungkus" hasil.

Di sini adalah apa yang kita lakukan. Ketika kita ingin menggabungkan dua fungsi F dan G, kita ikuti proses ini (yang disebut mengikat):

  1. Menghitung "hasil" dari F tapi don't menggabungkan mereka.
  2. Menghitung hasil dari penerapan G untuk masing-masing dari F's hasil secara terpisah, menghasilkan satu kumpulan hasil koleksi.
  3. Meratakan tingkat 2-koleksi dan menggabungkan semua hasil.

Kembali ke contoh kita, let's menggabungkan (mengikat) fungsi dengan dirinya sendiri menggunakan cara baru "mengikat" fungsi:

  • 1 -> [1] -> [1] (bungkus input, dua kali)
  • 1 -> [] -> [] (membuang input, bungkus kehampaan dalam daftar, dua kali)
  • 1 -> [2] -> [3] (tambahkan 1, kemudian tambahkan 1 lagi, dan bungkus hasilnya.)
  • 3 -> [4,6] -> [5,8,7,12] (tambahkan 1 untuk input, dan juga memperbanyak input sebesar 2, menjaga kedua hasil, kemudian melakukannya lagi untuk kedua hasil, dan kemudian membungkus hasil akhir dalam daftar.)

Ini cara yang lebih canggih menggabungkan fungsi adalah asosiatif (berikut dari bagaimana fungsi komposisi adalah asosiatif bila anda tidak't melakukan mewah pembungkus barang-barang).

Mengikat semuanya bersama-sama,

  • sebuah monad adalah struktur yang mendefinisikan sebuah cara untuk menggabungkan (hasil) fungsi,
  • analog dengan bagaimana sebuah monoid adalah struktur yang mendefinisikan sebuah cara untuk menggabungkan objek,
  • di mana metode kombinasi asosiatif,
  • dan di mana ada khusus 'No-op' yang dapat dikombinasikan dengan sesuatu untuk hasil di sesuatu tidak berubah.

Catatan

Ada banyak cara untuk "bungkus" hasil. Anda dapat membuat daftar, atau satu set, atau membuang semua tapi hasil pertama sambil mengingatkan jika tidak ada hasil, pasang sespan dari negara, mencetak pesan log, dll, dll.

I've bermain sedikit longgar dengan definisi-definisi di harapan mendapatkan ide penting di seluruh intuitif.

I've modern hal-hal sedikit dengan bersikeras bahwa kami monad beroperasi pada fungsi dari jenis a -> [a]. Bahkan, monads bekerja pada fungsi dari jenis a -> m b, tetapi generalisasi adalah jenis detail teknis yang isn't utama wawasan.

Komentar (6)

Pertama, ekstensi dan perpustakaan yang kita're akan menggunakan:

{-# LANGUAGE RankNTypes, TypeOperators #-}

import Control.Monad (join)

Dari jumlah tersebut, RankNTypes adalah satu-satunya yang's benar-benar penting untuk di bawah ini. Saya pernah menulis penjelasan dari RankNTypes bahwa beberapa orang tampaknya telah menemukan berguna, jadi saya'll lihat itu.

Mengutip Tom Crockett's jawaban yang sangat baik, kita memiliki:

A monad adalah...

  • Sebuah endofunctor, T : X -> X
  • Sebuah transformasi alam, μ : T × T -> T, dimana × sarana functor komposisi
  • Sebuah transformasi alam, η : I -> T, dimana I adalah identitas endofunctor pada X

...memuaskan undang-undang ini:

  • μ(μ(T × T) × T)) = μ(T × μ(T × T))
  • μ(η(T)) = T = μ(T(η))

Bagaimana kita menerjemahkan ini untuk Haskell kode? Nah, let's mulai dengan gagasan alamitransformasi**:

-- | A natural transformations between two 'Functor' instances.  Law:
--
-- > fmap f . eta g == eta g . fmap f
--
-- Neat fact: the type system actually guarantees this law.
--
newtype f :-> g =
    Natural { eta :: forall x. f x -> g x }

Jenis bentuk f :-> g adalah analog dengan tipe fungsi, tapi bukannya memikirkan hal itu sebagai fungsi antara dua jenis (dari jenis *), menganggapnya sebagai morphism antara dua functors (masing-masing dari jenis * -> *). Contoh:

listToMaybe :: [] :-> Maybe
listToMaybe = Natural go
    where go [] = Nothing
          go (x:_) = Just x

maybeToList :: Maybe :-> []
maybeToList = Natural go
    where go Nothing = []
          go (Just x) = [x]

reverse' :: [] :-> []
reverse' = Natural reverse

Pada dasarnya, di Haskell, alami transformasi fungsi dari beberapa jenis f x untuk tipe lain g x seperti itu x jenis variabel adalah "tidak dapat diakses" ke pemanggil. Jadi misalnya, sort :: Ord a => [a] -> [a] tidak dapat dibuat menjadi transformasi alam, karena itu's "pilih-pilih" tentang yang jenis kita dapat instantiate untuk a. Salah satu cara yang intuitif sering saya gunakan untuk berpikir ini adalah sebagai berikut:

  • Sebuah functor adalah cara yang beroperasi di isi sesuatu tanpa menyentuh struktur.
  • Sebuah transformasi alam adalah cara operasi pada struktur sesuatu tanpa menyentuh atau melihat isi.

Sekarang, dengan keluar dari jalan, let's mengatasi klausul definisi.

Klausa pertama adalah "suatu endofunctor, T : X -> X." Nah, setiap Functor di Haskell adalah endofunctor dalam apa yang orang-orang sebut "Hask kategori," benda yang Haskell jenis (jenis *) dan yang morphisms yang Haskell fungsi. Ini kedengarannya seperti sebuah rumit pernyataan, tapi itu's sebenarnya sangat sepele. Semua itu berarti bahwa Functor f :: * -> * memberi anda sarana untuk membangun jenis f a :: * untuk setiap a :: * dan fungsi fmap f :: f a -> f b keluar dari f :: a -> b, dan bahwa mereka mematuhi functor undang-undang.

Kedua klausa: Identitas functor di Haskell (yang datang dengan Platform, sehingga anda hanya dapat mengimpor) didefinisikan dengan cara ini:

newtype Identity a = Identity { runIdentity :: a }

instance Functor Identity where
    fmap f (Identity a) = Identity (f a)

Sehingga transformasi alam η : I -> T dari Tom Crockett's definisi ini dapat ditulis dengan cara ini untuk setiap Ketunggalan misalnya t:

return' :: Monad t => Identity :-> t
return' = Natural (return . runIdentity)

Kalimat ketiga: komposisi dua functors di Haskell dapat didefinisikan dengan cara ini (yang juga dilengkapi dengan Platform):

newtype Compose f g a = Compose { getCompose :: f (g a) }

-- | The composition of two 'Functor's is also a 'Functor'.
instance (Functor f, Functor g) => Functor (Compose f g) where
    fmap f (Compose fga) = Compose (fmap (fmap f) fga)

Sehingga transformasi alam μ : T × T -> T dari Tom Crockett's definisi ini dapat ditulis seperti ini:

join' :: Monad t => Compose t t :-> t
join' = Natural (join . getCompose)

Pernyataan bahwa ini adalah sebuah monoid dalam kategori endofunctors maka berarti bahwa Menulis (sebagian diterapkan untuk hanya dua parameter pertama) adalah asosiatif, dan bahwa Identitas adalah elemen identitas. I. e., yang berikut isomorphisms mengadakan:

  • Menulis f (Compose g h) ~= Menyusun (Compose f g) h
  • Menulis f Identitas ~= f
  • Menulis Identitas g ~= g

Ini sangat mudah untuk membuktikan karena Menulis dan Identitas keduanya didefinisikan sebagai type, dan Haskell Laporan mendefinisikan semantik type sebagai sebuah isomorphism antara jenis yang didefinisikan dan jenis argumen untuk type's data konstruktor. Jadi misalnya, let's membuktikan Menulis f Identitas ~= f:

Compose f Identity a
    ~= f (Identity a)                 -- newtype Compose f g a = Compose (f (g a))
    ~= f a                            -- newtype Identity a = Identity a
Q.E.D.
Komentar (4)

Catatan: Tidak ada, ini isn't benar. Di beberapa titik ada komentar di jawaban ini Dan Piponi dirinya mengatakan bahwa penyebab dan efek di sini justru sebaliknya, bahwa ia menulis artikel dalam menanggapi James Iry's menyindir. Tapi itu tampaknya telah dihapus, mungkin oleh beberapa kompulsif lebih rapi.

Di bawah ini adalah asli saya menjawab.


It's sangat mungkin bahwa Iry telah membaca Dari Monoids untuk Monads, sebuah pos di mana Dan Piponi (sigfpe) berasal monads dari monoids di Haskell, dengan banyak diskusi dari kategori teori dan eksplisit menyebutkan "kategori endofunctors pada Hask" . Dalam kasus apapun, siapapun yang bertanya-tanya apa artinya untuk monad menjadi sebuah monoid dalam kategori endofunctors mungkin manfaat dari membaca ini derivasi.

Komentar (1)

Saya datang ke posting ini dengan cara pemahaman yang lebih baik tentang kesimpulan dari kutipan terkenal dari Mac Lane's Kategori Teori Untuk Bekerja Matematika. Dalam menggambarkan sesuatu, it's sering sama-sama berguna untuk menggambarkan apa itu's tidak. Fakta bahwa Mac Lane menggunakan deskripsi untuk menggambarkan Monad, yang mungkin berarti bahwa hal itu menggambarkan sesuatu yang unik untuk monads. Beruang dengan saya. Untuk mengembangkan pemahaman yang lebih luas dari pernyataan itu, saya percaya itu harus dibuat jelas bahwa dia adalah not menggambarkan sesuatu yang unik untuk monads; pernyataan sama-sama menjelaskan Aplikatif dan Panah antara lain. Untuk alasan yang sama kita dapat memiliki dua monoids pada Int (Produk dan Jumlah), kita dapat memiliki beberapa monoids pada X dalam kategori endofunctors. Tapi ada bahkan lebih untuk kesamaan. Kedua Monad dan Aplikatif memenuhi kriteria:

  • endo => setiap panah, atau morphism yang dimulai dan berakhir di tempat yang sama
  • functor => setiap panah, atau morphism antara dua Kategori

    (misalnya, di hari ke hari Pohon -> Daftar b, tapi dalam Kategori Pohon -> Daftar)

  • monoid => objek tunggal; yaitu, satu jenis, tetapi dalam konteks ini, hanya dalam hal eksternal lapisan; jadi, kita bisa't memiliki Pohon -> Daftar, hanya Daftar -> Daftar. Pernyataan menggunakan "Kategori..." Ini mendefinisikan ruang lingkup pernyataan ini. Sebagai contoh, Functor Kategori menjelaskan lingkup f * -> g *, yaitu, Setiap functor -> Setiap functor, misalnya, Pohon * -> Daftar * atau Pohon * -> Pohon *.

    Apa sebuah pernyataan Kategoris tidak menentukan menjelaskan di mana anything dan semuanya permitted.

    Dalam hal ini, dalam functors, * -> * aka a -> b tidak ditentukan yang berarti Apa saja -> Apa pun termasuk Sesuatu yang lain. Sebagai imajinasi saya melompat ke Int -> String, itu juga termasuk Integer -> Mungkin Int, atau bahkan Mungkin Ganda,- > Baik String Int di mana a :: Mungkin Double; b :: Baik berupa String Int. Jadi pernyataan yang datang bersama-sama sebagai berikut:

  • functor lingkup :: f a -> g b (yaitu, setiap parameter jenis untuk setiap parameter jenis)
  • endo + functor :: f a -> f b (yaitu, salah satu parameter dengan tipe yang sama parameterized jenis) ... kata secara berbeda,
  • sebuah monoid dalam kategori endofunctor Jadi, di mana kekuatan membangun ini? Untuk menghargai penuh dinamika, yang saya butuhkan untuk melihat yang khas gambar-gambar dari monoid (objek tunggal dengan apa yang tampak seperti sebuah identitas panah, :: objek tunggal -> satu objek), gagal untuk menggambarkan bahwa saya'm diizinkan untuk menggunakan panah parameterized dengan any number dari monoid nilai-nilai, dari one jenis objek yang diizinkan dalam Monoid. Endo, ~ identitas panah definisi kesetaraan ignores yang functor's type value dan baik jenis dan nilai yang paling dalam, "muatan" lapisan. Dengan demikian, kesetaraan kembali benar dalam setiap situasi di mana functorial jenis pertandingan (misalnya, tidak Ada -> Hanya * -> tidak Ada yang setara dengan Hanya * -> Hanya * -> Hanya * karena mereka berdua Mungkin -> Mungkin -> Mungkin).

    Sidebar: ~ luar konseptual, tetapi adalah yang paling kiri simbol di `f`. Ia juga menjelaskan apa "Haskell" membaca-in pertama (big picture); sehingga Jenis "di luar" dalam kaitannya dengan Jenis Nilai. Hubungan antara lapisan (rantai referensi) dalam pemrograman adalah tidak mudah untuk berhubungan dengan Kategori. Kategori Set digunakan untuk menggambarkan Jenis (Int, String, Mungkin Int dll.) yang termasuk Kategori Functor (parameterized Jenis). Referensi rantai: Functor Jenis, Functor nilai-nilai (elemen yang Functor's set, misalnya, apa-Apa, Hanya), dan pada gilirannya, segala sesuatu yang lain masing-masing functor nilai poin untuk. Dalam Kategori hubungan ini dijelaskan secara berbeda, misalnya, `kembali :: a -> m` dianggap alami transformasi dari satu Functor lain Functor, berbeda dari apa yang disebutkan sejauh ini. Kembali ke thread utama, semua dalam semua, untuk setiap didefinisikan tensor produk dan netral nilai, pernyataan berakhir menggambarkan yang luar biasa kuat komputasi membangun dilahirkan dari paradoks struktur:

  • di luar itu muncul sebagai satu objek (misalnya, :: Daftar); statis
  • tapi di dalam, memungkinkan banyak dinamika
  • setiap jumlah nilai dari jenis yang sama (misalnya, Kosong | ~NonEmpty) sebagai pakan ternak untuk fungsi-fungsi dari setiap tual membaca, keakraban. Tensor produk akan mengurangi jumlah input untuk nilai tunggal... untuk lapisan luar (~lipat yang mengatakan apa-apa tentang payload)
  • tak terbatas berbagai both jenis dan nilai-nilai untuk lapisan paling dalam Di Haskell, menjelaskan penerapan pernyataan penting. Kekuatan dan fleksibilitas dari membangun ini, sama sekali tidak ada hubungannya dengan monad per se. Dengan kata lain, membangun tidak bergantung pada apa yang membuat monad yang unik. Ketika mencoba untuk mencari tahu apakah untuk membangun kode dengan konteks berbagi untuk mendukung komputasi yang saling bergantung satu sama lain, terhadap perhitungan yang dapat dijalankan secara paralel, ini pernyataan terkenal, dengan sebanyak itu menjelaskan, tidak kontras antara pilihan Aplikatif, Panah dan Monads, melainkan adalah uraian dari berapa banyak mereka adalah sama. Untuk keputusan di tangan, pernyataan diperdebatkan. Hal ini sering disalahpahami. Pernyataan itu melanjutkan untuk menggambarkan join :: m (m a) -> m sebagai tensor produk untuk monoidal endofunctor. Namun, itu tidak mengartikulasikan bagaimana, dalam konteks ini, pernyataan, (<*>) bisa juga juga telah dipilih. Ini benar-benar adalah sebuah contoh dari enam/setengah lusin. Logika untuk menggabungkan nilai-nilai yang persis sama; input yang sama menghasilkan output yang sama dari masing-masing (tidak seperti Produk dan Jumlah monoids untuk Int karena mereka menghasilkan hasil yang berbeda ketika menggabungkan Ints). Jadi, untuk rekap: Sebuah monoid dalam kategori endofunctors menjelaskan:
   ~t :: m * -> m * -> m *
   and a neutral value for m *

(<*>) dan (>>=) keduanya memberikan akses simultan ke dua m nilai-nilai dalam rangka untuk menghitung satu nilai kembali. Logika yang digunakan untuk menghitung nilai kembali adalah persis sama. Jika bukan untuk bentuk yang berbeda dari fungsi-fungsi mereka mengukur (f :: a -> b versus k :: a -> m b) dan posisi parameter dengan pengembalian yang sama jenis perhitungan (yaitu, a -> b> b versus b ->- > b untuk setiap masing-masing), saya menduga kita bisa memiliki parameter yang monoidal logika, tensor produk, untuk digunakan kembali dalam kedua definisi tersebut. Sebagai latihan untuk membuat titik, mencoba dan menerapkan ~t, dan anda berakhir dengan (<*>) dan (>>=) tergantung pada bagaimana anda memutuskan untuk mendefinisikan forall a b. Jika poin terakhir saya adalah minimal konseptual benar, itu kemudian menjelaskan yang tepat, dan hanya komputasi perbedaan antara Aplikatif dan Monad: fungsi mereka mengukur. Dengan kata lain, perbedaannya adalah external untuk pelaksanaan jenis-jenis kelas. Kesimpulannya, dalam pengalaman saya sendiri, Mac Lane's terkenal kutipan tersebut, "goto" meme, sebuah tonggak bagi saya untuk referensi saat menavigasi jalan melalui Kategori untuk lebih memahami idiom yang digunakan dalam Haskell. Ia berhasil menangkap lingkup kapasitas komputasi yang kuat dibuat sangat mudah diakses di Haskell. Namun, ada ironi dalam bagaimana saya pertama kali disalahpahami pernyataan's penerapan di luar monad, dan apa yang saya harap disampaikan di sini. Segala sesuatu yang menggambarkan ternyata apa yang mirip antara Aplikatif dan Monads (dan Panah antara lain). Apa itu doesn't mengatakan justru yang kecil-kecil tapi berguna perbedaan di antara mereka. - E

Komentar (0)

Jawaban di sini melakukan pekerjaan yang sangat baik dalam mendefinisikan kedua monoids dan monads, namun, mereka masih don't tampaknya untuk menjawab pertanyaan:

Dan pada yang kurang penting diperhatikan, apakah ini benar dan jika demikian anda bisa memberikan penjelasan (mudah-mudahan salah satu yang dapat dipahami oleh seseorang yang doesn't memiliki banyak Haskell pengalaman)? Inti dari hal yang hilang di sini, adalah gagasan yang berbeda dari "monoid", yang disebut categorification lebih tepatnya -- salah satu dari monoid dalam monoidal kategori. Sayangnya Mac Lane's buku itu sendiri membuatnya sangat membingungkan: Semua mengatakan, sebuah monad di X adalah hanya sebuah monoid dalam kategori endofunctors dari X, dengan produk × diganti dengan komposisi endofunctors dan unit yang ditetapkan oleh identitas endofunctor.

Utama kebingungan

Mengapa hal ini membingungkan? Karena itu tidak mendefinisikan apa yang dimaksud "monoid dalam kategori endofunctors" dari X. Sebaliknya, kalimat ini menunjukkan mengambil sebuah monoid dalam himpunan semua endofunctors bersama-sama dengan functor komposisi sebagai operasi biner dan identitas functor sebagai monoidal unit. Yang bekerja baik-baik saja dan berubah menjadi sebuah monoid setiap subset dari endofunctors yang berisi identitas functor dan ditutup di bawah functor komposisi. Namun ini bukan interpretasi yang benar, yang buku gagal untuk membuat jelas pada tahap itu. Sebuah Monad f adalah tetap endofunctor, tidak subset dari endofunctors ditutup di bawah komposisi. Konstruksi umum adalah dengan menggunakan f untuk menghasilkan sebuah monoid dengan mengambil set dari semua k-lipat komposisi f^k = f(f (...)) f dengan dirinya sendiri, termasuk k=0 yang sesuai dengan identitas f^0 = id. Dan sekarang set S dari semua kekuatan ini untuk semua k>=0 memang sebuah monoid "dengan produk × diganti dengan komposisi endofunctors dan unit yang ditetapkan oleh identitas endofunctor". Dan belum:

  • Ini monoid S dapat didefinisikan untuk setiap functor f atau bahkan benar-benar untuk diri-peta X. Itu adalah monoid yang dihasilkan oleh f.
  • The monoidal struktur S yang diberikan oleh functor komposisi dan identitas functor memiliki apa-apa hubungannya dengan f menjadi atau tidak menjadi monad. Dan untuk membuat hal-hal lebih membingungkan, definisi "monoid dalam monoidal kategori" datang kemudian dalam buku seperti yang anda lihat dari daftar isi. Dan belum memahami gagasan ini benar-benar penting untuk memahami koneksi dengan monads.

    (Ketat) monoidal kategori

    Akan Bab VII pada Monoids (yang datang kemudian dari Bab VI pada Monads), kita menemukan definisi yang disebut ketat monoidal kategori sebagai triple (B, *, e), di mana B adalah kategori, *: B x B-> B a bifunctor (functor dengan hormat untuk masing-masing komponen dengan komponen lainnya tetap) dan e adalah satuan objek di B, memuaskan associativity dan kesatuan hukum yang:

(a * b) * c = a * (b * c)
a * e = e * a = a

untuk setiap benda a,b,c dari B, dan identitas yang sama untuk setiap morphisms a,b,c dengan e diganti dengan id_e, identitas morphism dari e. Sekarang instruktif untuk mengamati bahwa dalam kasus bunga, di mana B adalah kategori endofunctors dari X dengan alami transformasi sebagai morphisms, * yang functor komposisi dan e identitas functor, semua undang-undang ini puas, karena dapat langsung diverifikasi. Apa yang datang setelah dalam buku ini adalah definisi dari "super" monoidal kategori, dimana hukum hanya memegang modulo beberapa tetap alami transformasi memuaskan disebut koherensi hubungan, namun hal ini tidak penting bagi kami kasus endofunctor kategori.

Monoids di monoidal kategori

Akhirnya, di bagian 3 "Monoids" Bab VII, yang sebenarnya definisi yang diberikan:

Sebuah monoid c di monoidal kategori (B, *, e) adalah sebuah objek dari B dengan dua panah (morphisms)

mu: c * c -> c
nu: e -> c

membuat 3 diagram komutatif. Ingat bahwa dalam kasus kami, ini adalah morphisms dalam kategori endofunctors, yang alami transformasi yang sesuai untuk tepatnya join dan kembali untuk monad. Koneksi menjadi lebih jelas ketika kita membuat komposisi * yang lebih eksplisit, mengganti c * c dengan c^2, di mana c adalah kami monad. Akhirnya, perhatikan bahwa 3 diagram komutatif (dalam definisi sebuah monoid dalam monoidal kategori) yang ditulis untuk umum (non-ketat) monoidal kategori, sementara dalam kasus kami semua alami transformasi yang timbul sebagai bagian dari monoidal kategori yang benar-benar identitas. Yang akan membuat diagram persis sama seperti orang-orang dalam pengertian monad, membuat korespondensi lengkap.

Kesimpulan

Singkatnya, setiap monad adalah dengan definisi yang endofunctor, maka objek dalam kategori endofunctors, di mana monadic join dan kembali operator memenuhi definisi suatu monoid dalam tertentu (ketat) monoidal kategori. Sebaliknya, setiap monoid dalam monoidal kategori endofunctors adalah dengan definisi triple (c, mu, nu) yang terdiri dari objek dan dua panah, misalnya alam transformasi dalam kasus kami, memuaskan hukum yang sama sebagai monad. Akhirnya, perhatikan perbedaan utama antara (klasik) monoids dan lebih umum monoids di monoidal kategori. Dua panah mu dan nu di atas tidak lagi biner operasi dan unit dalam satu set. Sebaliknya, anda harus tetap satu endofunctor c. Yang functor komposisi * dan identitas functor sendiri tidak memberikan struktur yang lengkap yang dibutuhkan untuk monad, meskipun yang membingungkan komentar di buku ini. Pendekatan lain akan dibandingkan dengan standar monoid C dari semua self-peta dari kumpulan A, di mana operasi biner adalah komposisi, yang dapat dilihat untuk memetakan standar produk cartesian C x C menjadi C. Lewat ke categorified monoid, kami mengganti produk cartesian x dengan functor komposisi *, dan operasi biner akan diganti dengan transformasi alam mu dari c * c untuk c, yang merupakan kumpulan dari bergabung operator

join: c(c(T))->c(T)

untuk setiap objek T (type dalam pemrograman). Dan identitas unsur-unsur klasik monoids, yang dapat diidentifikasi dengan gambar peta dari tetap satu-titik-set, bisa diganti dengan koleksi yang kembali operator

return: T->c(T) 

Tapi sekarang tidak ada lagi cartesian produk, sehingga tidak ada pasangan dari unsur-unsur dan dengan demikian tidak ada operasi biner.

Komentar (0)