Tidak ada batasan sama sekali! Ketika saya mulai belajar dasar-teori kategori untuk konstruktor tipe, titik ini juga membingungkan saya. Kita akan membahasnya. Tapi pertama-tama, izinkan saya menjernihkan kebingungan. Dua kutipan ini:
functor tersebut hanya dapat memiliki kategori target sebagai kategori yang dibangun menggunakan konstruktor tipe
dan
orang mungkin menganggap functors memiliki kategori apa pun sebagai target dari functor, misalnya kategori semua jenis Haskell
tunjukkan bahwa Anda salah memahami apa yang dimaksud dengan functor (atau paling tidak, Anda menyalahgunakan terminologi).
Functors tidak membangun kategori. Functor adalah pemetaan antar kategori. Functors membawa objek dan morfisme (jenis dan fungsi) dalam kategori sumber ke objek dan morfisme dalam kategori target.
Perhatikan bahwa ini berarti functor benar-benar sepasang pemetaan: pemetaan pada objek F_obj dan pemetaan pada morphisms F_morph . Dalam Haskell, bagian objek F_obj dari functor adalah nama konstruktor tipe (misalnya List
), sedangkan bagian morfisme adalah fungsi fmap
(terserah kompilator Haskell untuk memilah mana yang fmap
kita rujuk dalam setiap ekspresi yang diberikan). Jadi, kita tidak bisa mengatakan itu List
adalah functor; hanya kombinasi List
dan fmap
fungsi. Namun, orang-orang menyalahgunakan notasi; pemrogram memanggil List
functor, sementara ahli teori kategori menggunakan simbol yang sama untuk merujuk ke kedua bagian dari functor.
Lebih jauh lagi, dalam pemrograman, hampir semua functors adalah endofunctors , yaitu kategori sumber dan target adalah sama - kategori semua tipe dalam bahasa kita. Sebut kategori ini Jenis . Endofunctor F pada Tipe memetakan tipe T ke tipe FT lainnya dan fungsi T -> S ke fungsi lain FT -> FS . Pemetaan ini tentu saja harus mematuhi hukum functor.
Menggunakan List
sebagai contoh: kita memiliki konstruktor tipe List : Type -> Type
, dan fungsi fmap: (a -> b) -> (List a -> List b)
, yang bersama-sama membentuk functor. T
Ada satu poin terakhir untuk dijernihkan. Menulis List int
tidak membuat daftar bilangan bulat tipe baru. Jenis ini sudah ada . Itu adalah objek dalam Jenis kategori kami . List Int
hanyalah cara untuk merujuknya.
Sekarang, Anda bertanya-tanya mengapa functor tidak dapat memetakan tipe, katakan, Int
atau String
. Tapi, itu bisa! Orang hanya harus menggunakan functor identitas. Untuk kategori C apa saja , functor identitas memetakan setiap objek ke dirinya sendiri dan morfisme untuk dirinya sendiri. Sangat mudah untuk memverifikasi pemetaan ini memenuhi hukum functor. Di Haskell, ini akan menjadi konstruktor tipe id : * -> *
yang memetakan setiap tipe untuk dirinya sendiri. Misalnya, id int
evaluasi ke int
.
Selain itu, seseorang bahkan dapat membuat functors konstan , yang memetakan semua tipe ke tipe tunggal. Misalnya, functor ToInt : * -> *
, di mana ToInt a = int
untuk semua jenis a
, dan memetakan semua morfisme ke fungsi identitas bilangan bulat: fmap f = \x -> x