Обобщение класса Functor для превращения в MultiFunctor? - PullRequest
0 голосов
/ 13 января 2019

Я учусь у " бесплатных аппликативных функторов ". Конечно, вопрос, который я собираюсь задать, отчасти не соответствует основной идее статьи, но все же ...

... на странице 6 предпринята попытка обобщить Functor до MultiFunctor:

class Functor f ⇒ MultiFunctor f where
    fmap0 :: a → f a
    fmap1 :: (a → b) → f a → f b
    fmap1 = fmap
    fmap2 :: (a → b → c) → f a → f b → f c
    ...

Я не могу понять, как это определение оправдано с точки зрения теории категорий: fmap2 представляется просто бифунктором, т. Е. Функтором, определенным для категории продуктов . По определению, категория продукта задается всеми возможными упорядоченными парами объектов, и морфизмы также являются парами, следовательно: fmap2 :: (a -> a', b -> b') -> (f a, f b) -> (f a', f b') выглядит и ощущается как более подходящая сигнатура.

Я могу понять способ мышления, стоящий за выбором (a -> b -> c) -> f a -> f b -> f c: это просто самый очевидный способ взять известную (a -> b) -> f a -> f b подпись и заставить ее работать с двоичными функциями, а не с унарными. Но действительно ли MultiFunctor (заданное выше определением) на самом деле является би- / мультифунктором в том смысле, в котором теория категорий этого ожидает?

P.S. Причина, по которой мне любопытно, заключается в том, что кажется, что не может добраться до Applicative, обобщив Functor, хотя в статье говорится, что можно.

Ответы [ 2 ]

0 голосов
/ 13 января 2019

Я думаю, что угол теории категорий, который вы используете, неверен Существует класс Bifunctor (с картой типа (a -> b) -> (c -> d) -> f a c -> f b d), но это не то, чем является это обобщение. Если кто-то отключает некоторые функции, то подпись fmap2 выглядит следующим образом:

fmap2 :: ((a,b) -> c) -> (f a, f b) -> f c

И, рассматривая fmap2 id, мы видим, что мы реализуем не бифунктор, а декартовой функтор (т.е. моноидальный функтор между декартовыми категориями), причем fmap2 id :: (f a, f b) -> f (a,b) является естественным преобразованием:

\mu_{x,y} : F(x) \otimes F(y) \to F(x \otimes y)

Затем можно получить аппликатив из этого Multifunctor обобщения. Просто измените pure на fmap0 и (<*>) на fmap2 ($).

0 голосов
/ 13 января 2019

Давайте начнем с очевидного: fmap0 чисто.

Вот ошибка, с которой вы ошиблись: fmap2 - это liftA2.

(bimap очень отличается - (a -> b) -> (c -> d) -> f a b -> f c d)

И если вы вернетесь к определению для Applicative, вы увидите, что у него есть реализация по умолчанию (<*>), то есть liftA2 id, которая позволяет вам определять его в терминах чистый и либо liftA2, либо (<*>).

Так что да, этот класс эквивалентен Applicative.

...