Почему в Хаскелле есть различие между со и контравариантными функторами, а не в теории категорий? - PullRequest
0 голосов
/ 19 декабря 2018

Этот ответ с точки зрения теории категорий включает следующее утверждение:

... правда в том, что нет никакого реального различия между со и контравариантным функтором, потому что каждый функторявляется просто ковариантным функтором.

...

Более подробно контравариантный функтор F из категории C в категорию D является не более чем (ковариантным) функтором типа F: C op → D, из противоположной категории C в категорию D.

С другой стороны, у Хаскелла Functor и Contravariant просто требуют, чтобы fmap и contramap соответственно были определены для экземпляра.Это говорит о том, что с точки зрения Haskell существуют объекты, которые Contravariant, но не являются Functor s (и наоборот).

Таким образом, похоже, что в теории категорий "нет реального различия междусо и контравариантные функторы "в то время как в Haskell существует различие между Contravariant и Functor.

Я подозреваю, что это различие имеет отношение ко всей реализации в Haskell, происходящей в Hask, но я не уверен,

Мне кажется, я понимаю каждую из теорий категорий и перспективы Хаскелла по-своему, но я изо всех сил пытаюсь найти интуицию, которая связывает их.

Ответы [ 3 ]

0 голосов
/ 19 декабря 2018

Это для удобства.

Можно обойтись с помощью более общего Functor класса и определить экземпляры для endofunctors на Hask (соответствующие нашим существующим Functor) и функторамот Hask ^ op до Hask (соответствует нашему существующему Contravariant).Но это происходит за счет переносных познавательных затрат и довольно буквальных синтаксических затрат: для выбора экземпляра необходимо полагаться на вывод типа или аннотации типов, и существуют явные преобразования (именуемые в стандартной библиотеке Op и getOp) ви из Hask ^ op.

Использование имен fmap и contramap уменьшает обе затраты: читателям не нужно запускать Хиндли-Милнера в своей голове, чтобы решить, какой экземпляр выбирается, когда он однозначени авторам не нужно давать явные преобразования или аннотации типов для выбора экземпляра в тех случаях, когда он неоднозначен.

(На самом деле я немного переписываю историю здесь. Причина real это потому, что дизайнеры языка думали, что специализированный Functor будет полезен и не предполагал или не видел необходимости в более общем Functor. Люди приходили позже и замечали, что это иногда будет полезно. Но опыт работы собобщенный класс Functor показывает, что может быть утомительным, и что специализированный классes для наиболее распространенных случаев в конце концов оказывается на удивление хорошо подходящим по причинам, описанным выше.)

0 голосов
/ 19 декабря 2018

Представьте себе, что на минуту у нас было что-то вроде следующего.

class MoreAccurateFunctor c d f where
  fmap :: c a b -> d (f a) (f b)

Поскольку (->) является экземпляром Category (это Hask ), мы бы получилиFunctor ~ MoreAccurateFunctor (->) (->).

Теперь представьте, что у нас есть Dual (->), двойная категория (->) (это будет Hask Op , и у нас будет Dual (->) a b ~ (b -> a)), у нас было бы это Contravariant ~ MoreAccurateFunctor (Dual (->)) (->).

Я не знаю, помогает ли это, но идея состоит в том, чтобы указать на тот факт, что Functor и Contravariant являются двумя специализациями MoreAccurateFunctor, в то время какэтот последний класс ближе к определению функтора в теории категорий.

0 голосов
/ 19 декабря 2018

Математически рассмотрение контравариантных функторов как отдельного класса функторов является просто условным обозначением;контравариантный функтор F : C -> D всегда можно определить как ковариантный функтор F' : C^{op} -> D, поэтому избавление от идеи контравариантных функторов просто заставит вас говорить о противоположной категории в явном виде.

В Haskell *Класс 1007 * представляет собой эндофунктор в (предполагаемой) категории Hask .Нет удобного способа представления HASK OP напрямую (или, по крайней мере, не в форме, которая помогает нам определять функторы из этой категории), а также не существует класс типов, который определяет exofunctor *поэтому вместо этого мы определяем класс Contrafunctor, функция которого contramap может перевернуть стрелку из, так сказать, Hask"по требованию".


* Is "exofunctor"реальный срок?Я просто выдумал, чтобы указать функтор, который не является эндофунктором.

...