Есть ли концепция чего-то вроде ко-аппликативных функторов, сидящих между комонадами и функторами?

17

Любая монада также является аппликативным функтором, а любой аппликативный функтор - функтором. Также любая комонада является функтором. Существует ли похожая концепция между комонадами и функторами, что-то вроде ко-аппликативного функтора, и каковы его свойства?

ФУНКТОРЫФУНКТОРЫАппликативные функторы???МонадыComonads

Обновление: я был бы также заинтересован в возможном использовании такой концепции.

Петр Пудлак
источник
Вы уверены, что не искали Comonads -> ??? -> Кофункторы?
Иосия
1
@josiah Нет, насколько я знаю, комонады - это функторы , а не кофункторы.
Петр Пудлак
1
Разве не делится этот недостающий кусок?
Гас

Ответы:

15

Прежде всего:

Любая монада также является аппликативным функтором, а любой аппликативный функтор - функтором.

Это верно в контексте Haskell, но (читается Applicativeкак «сильный слабый моноидальный функтор») не в общем, по довольно тривиальной причине, по которой вы можете иметь «аппликативные» функторы между различными моноидальными категориями, тогда как монады (и комонады) являются эндофункторами ,

Кроме того, отождествление Applicativeс сильными слабыми моноидальными функторами немного вводит в заблуждение, поскольку для обоснования имени (и сигнатуры типа (<*>)) требуется функтор между замкнутыми моноидальными категориями, который сохраняет как моноидальную структуру, так и внутренний гом . Это можно правдоподобно назвать «слабым замкнутым моноидальным функтором», за исключением того, что функтор между моноидальными замкнутыми категориями, который сохраняет одно свойство, сохраняет другое очевидным образом . Так Applicativeописывает только endofunctors на Hask сохранения моноидальных структур (,), его экземпляры получить много свойств автоматически, включая их силу , которые , таким образом , могут быть опущены.

Кажущаяся связь с Monad, возможно, является артефактом неявных ограничений на Applicativeсовпадение аспектов их соответствующих моноидных структур, счастливое совпадение, которое, к сожалению, не переживает дуализации.

Так же, как комонада категории является монадой на C o p , оплаксный моноидальный функтор C D является слабым моноидальным функтором C o pD o p . Но H a s k o p не является моноидально замкнутым , и кооперация , не включающая в себя применение функции, вряд ли заслуживает названия. В любом случае, результат не был бы ужасно интересным:ССоп СDСопDопЧАСasКопApplicative

class (Functor f) => CoMonoidal f where
    counit :: f () -> ()
    cozip :: f (a, b) -> (f a, f b)

ApplicativeЧАСasКопnewtype Op b a = Op (a -> b)ЧАСasКбaЧАСasКопOp b aЧАСasК

ЧАСasКApplicative

class (Functor f) => CoApplicative f where
    copure :: f a -> a
    coap :: (f a -> f b) -> f (a -> b)

Конечно, добавление duplicate :: f a -> f (f a)к copureбудет производить комонаду (при условии соблюдения законов). Но нет очевидной связи между - coapчем бы это ни было - и extend :: (f a -> b) -> f a -> f b. При сравнении типов становится ясно, что дуализация происходит по-разному: комоноидальные структуры лежат в основе duplicateи cozipимеют мало общего друг с другом или с coap(что, вероятно, в любом случае не имеет смысла), тогда как liftA2 (,)и (<*>)являются эквивалентными и могут быть получены из join.

Другой возможный способ дуализации Applicative, который имеет еще меньшее отношение к комадам, заключается в рассмотрении контравариантных моноидальных функторов:

class (Contravariant f) => ContraMonoidal f where
    contraunit :: f a
    contrazip :: f a -> f b -> f (Either a b)

ЧАСasКопb <~ acontracurry :: (Either c b <~ a) -> (c <~ (b <~ a))contraapply :: b -> Either a (a <~ b)

ЧАСasКCoApplicative

Однако в моноидальной закрытой категории, более гостеприимной к дуализации, вам может повезти больше. В частности, я считаю, что обе Kleisli (Cont r)и их противоположные категории моноидально замкнуты, так что это может быть лучшим контекстом для изучения этих идей.

CA Макканн
источник
Сравнивая ваш ответ с cstheory.stackexchange.com/a/22302/989 , вы удивляетесь, что вы не превращаете продукты в суммы. Конечно, вы правы в том, что у Хаск нет категориальных сумм; но если вы хотите ограничиться категорией общих программ (как в Agda), давайте представим, что сейчас она установлена, эта проблема исчезает. (Я не говорю, что Set ^ op закрыт моноидально, но я подозреваю, что это говорит о том, что я говорю).
Blaisorblade
8

В этом посте на SO я нашел интересный ответ - решающие функторы . Если мы заменим ()на Void, (,)по Either и реверс стрелки, мы получим:

class Functor f => Decisive f where
    nogood :: f Void -> Void
    orwell :: f (Either s t) -> Either (f s) (f t)

В блоге также приведены некоторые законы, которых придерживаются решающие функторы.

И каждый Comonadтакже Decisive:

instance Comonad c => Decisive c where
    nogood = counit
    orwell story = case counit story of
                     Left s  -> fmap (either id (const s)) story
                     Right t -> fmap (either (const t) id) story 

Таким образом, решающие функторы вписываются между функторами и комонадами так же, как аппликативные функторы вписываются между функторами и монадами.

Петр Пудлак
источник
6

Макбрайд и Паттерсон (раздел 7) показывают, что аппликативный функтор, также известный как идиома, является сильным слабым моноидальным функтором . Вы ищете сильный моноидальный функтор колакса, также известный как сильный моноидальный функтор оплакс . Как упомянуто в комментарии, моноидальный функтор oplax является слабым моноидальным функтором между противоположными категориями, который в конечном итоге является комоноидальной версией слабого моноидального функтора.

Нарисуйте диаграммы, переверните стрелки!

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

Дэйв Кларк
источник
По какой-то причине стандартным термином кажется «оплакс моноидальный функтор». Идея заключается в слабом моноидальном функторе между противоположными категориями, который в конечном итоге является комоноидальной версией слабого моноидального функтора. Использование «colax comonoidal» является избыточным или эквивалентным «слабому monoidal».
CA Макканн
Я переборщил с "со". Я исправлю свой ответ.
Дэйв Кларк