Там нет никаких ограничений на всех! Когда я начал изучать теоретико-категорийную основу для конструкторов типов, этот момент меня и смутил. Мы доберемся до этого. Но сначала позвольте мне прояснить некоторую путаницу. Эти две цитаты:
такой функтор может иметь только в качестве целевой категории категорию, созданную с использованием конструктора типа
и
можно думать о функторах, имеющих любую категорию как цель функтора, например, категорию всех типов Haskell
покажите, что вы неправильно понимаете, что такое функтор (или, по крайней мере, вы неправильно используете терминологию).
Функторы не сооружать категории. Функтор - это отображение между категориями. Функторы переносят объекты и морфизмы (типы и функции) в исходной категории к объекту и морфизмы в целевой категории.
Обратите внимание, что это означает, что функтор - это действительно пара отображений: отображение объектов F_obj и отображение морфизмов F_morph . В Haskell объектная часть F_obj функтора - это имя конструктора типа (например List), в то время как часть морфизма - это функция fmap(компилятор Haskell должен разобраться, на что fmapмы ссылаемся в любом данном выражении). Таким образом, мы не можем сказать, что Listэто функтор; только комбинация Listи fmapявляется функтором. Тем не менее, люди злоупотребляют нотацией; программисты вызывают Listфунктор, в то время как теоретики категорий используют один и тот же символ для ссылки на обе части функтора.
Кроме того, в программировании почти все функторы являются эндофункторами , то есть исходная и целевая категории одинаковы - категория всех типов в нашем языке. Давайте назовем эту категорию типом . Endofunctor F в Type отображает тип T в другой тип FT, а функцию T -> S в другую функцию FT -> FS . Это отображение должно, конечно, подчиняться законам функторов.
В Listкачестве примера: у нас есть конструктор типа List : Type -> Typeи функция fmap: (a -> b) -> (List a -> List b), которые вместе образуют функтор. T
Есть один последний момент, чтобы прояснить. Запись List intне создает новый тип списков целых чисел. Этот тип уже существовал . Это был объект в нашей категории Type . List Intэто просто способ сослаться на это.
Теперь вам интересно, почему функтор не может сопоставить тип, скажем, Intили String. Но это может! Нужно просто использовать функтор идентичности. Для любой категории C функтор идентичности отображает каждый объект на себя и морфизм на себя. Нетрудно убедиться, что это отображение удовлетворяет законам функторов. В Haskell это будет конструктор типов, id : * -> *который отображает каждый тип на себя. Например, id intоценивает до int.
Более того, можно даже создавать постоянные функторы, которые отображают все типы в один тип. Например, функтор ToInt : * -> *, где ToInt a = intдля всех типов a, и отображает все морфизмы в целочисленную функцию идентичности: fmap f = \x -> x