Foo bebas merupakan hal paling sederhana yang memenuhi semua hukum 'foo'. Dengan kata lain itu memenuhi hukum yang diperlukan untuk menjadi foo dan tidak ada yang ekstra.
Functor pelupa adalah salah satu yang "lupa" bagian dari struktur saat berjalan dari satu kategori ke yang lain.
Fungsi yang diberikan F : D -> C
, dan G : C -> D
, kita katakan F -| G
, F
dibiarkan bersebelahan dengan G
, atau berbelok ke G
kanan F
setiap kali, a: b F a -> b
adalah isomorfik a -> G b
, di mana panah berasal dari kategori yang sesuai.
Secara formal, functor gratis dibiarkan berdekatan dengan functor yang pelupa.
Monoid Gratis
Mari kita mulai dengan contoh sederhana, monoid gratis.
Ambil monoid, yang didefinisikan oleh beberapa operator set T
, fungsi biner untuk mash sepasang elemen bersama-sama f :: T → T → T
, dan unit :: T
, seperti bahwa Anda memiliki hukum asosiatif, dan hukum identitas: f(unit,x) = x = f(x,unit)
.
Anda dapat membuat functor U
dari kategori monoids (di mana panah adalah homomorfisma monoid, yaitu, mereka memastikan mereka memetakan unit
ke unit
monoid lain, dan bahwa Anda dapat menyusun sebelum atau setelah pemetaan ke monoid lain tanpa mengubah makna) ke kategori set (di mana panah hanya panah fungsi) yang 'lupa' tentang operasi dan unit
, dan hanya memberi Anda set operator.
Kemudian, Anda dapat mendefinisikan functor F
dari kategori set kembali ke kategori monoids yang dibiarkan bersebelahan dengan functor ini. Functor itu adalah functor yang memetakan set a
ke monoid [a]
, di mana unit = []
, dan mappend = (++)
.
Jadi untuk meninjau contoh kita sejauh ini, di pseudo-Haskell:
U : Mon → Set -- is our forgetful functor
U (a,mappend,mempty) = a
F : Set → Mon -- is our free functor
F a = ([a],(++),[])
Kemudian untuk menunjukkan F
itu gratis, kita perlu menunjukkan bahwa itu dibiarkan bersebelahan dengan U
, sebuah fungsi yang pelupa, yaitu, seperti yang kita sebutkan di atas, kita perlu menunjukkan bahwa
F a → b
isomorfik untuk a → U b
sekarang, ingat bahwa target F
berada dalam kategori Mon
monoids, di mana panah adalah homomorfisma monoid, jadi kita perlu untuk menunjukkan bahwa homomorfisma monoid [a] → b
dapat digambarkan secara tepat dengan fungsi dari a → b
.
Dalam Haskell, kita menyebut sisi dari ini yang hidup dalam Set
(eh,, Hask
kategori tipe Haskell yang kita pura-pura adalah Set), adil foldMap
, yang ketika dikhususkan Data.Foldable
untuk dari memiliki tipe Monoid m => (a → m) → [a] → m
.
Ada konsekuensi yang mengikuti dari ini menjadi tambahan. Khususnya jika Anda lupa maka membangun dengan gratis, lalu lupakan lagi, sama seperti Anda lupa sekali, dan kita bisa menggunakan ini untuk membangun monadik bergabung. sejak UFUF
~ U(FUF)
~ UF
, dan kita bisa lulus dalam homomorfisma identitas monoid dari [a]
ke [a]
melalui isomorfisma yang mendefinisikan adjunction kami, mendapatkan bahwa daftar isomorfisma dari [a] → [a]
adalah fungsi dari jenis a -> [a]
, dan ini hanya kembali untuk daftar.
Anda dapat menyusun semua ini lebih langsung dengan menggambarkan daftar dalam istilah ini dengan:
newtype List a = List (forall b. Monoid b => (a -> b) -> b)
Monad Gratis
Jadi, apa itu Monad Gratis ?
Ya, kami melakukan hal yang sama dengan yang kami lakukan sebelumnya, kami mulai dengan functor U yang pelupa dari kategori monad di mana panah adalah homomorfisma monad ke kategori endofunctor di mana panah adalah transformasi alami, dan kami mencari functor yang dibiarkan berdekatan untuk itu.
Jadi, bagaimana ini berhubungan dengan gagasan tentang monad gratis seperti yang biasanya digunakan?
Mengetahui bahwa sesuatu adalah monad bebas Free f
,, memberitahu Anda bahwa memberi homomorfisme monad dari Free f -> m
, adalah hal yang sama (isomorfik ke) dengan memberikan transformasi alami (homomorfisme functor) dari f -> m
. Ingat F a -> b
harus isomorfik agar a -> U b
F dibiarkan bersebelahan dengan U. U di sini memetakan monad ke functors.
F setidaknya isomorfis dengan Free
tipe yang saya gunakan dalam free
paket saya tentang peretasan.
Kita juga dapat membangunnya dalam analogi yang lebih ketat dengan kode di atas untuk daftar gratis, dengan mendefinisikan
class Algebra f x where
phi :: f x -> x
newtype Free f a = Free (forall x. Algebra f x => (a -> x) -> x)
Cofree Comonads
Kita dapat membangun sesuatu yang serupa, dengan melihat adjoint yang tepat ke functor yang pelupa dengan asumsi itu ada. Sebuah functor cofree hanyalah adjoin kanan / ke functor pelupa, dan dengan simetri, mengetahui sesuatu adalah comofad cofree sama dengan mengetahui bahwa memberikan homomorfisme comonad dari w -> Cofree f
adalah hal yang sama seperti memberikan transformasi alami dari w -> f
.