Чи існує концепція чимось на зразок коплікативних функторів, що сидять між комоданами та функторами?


17

Будь-яка монада також є прикладним функціонером, а будь-який прикладний функтор - функтор. Також будь-яка команда є функтором. Чи існує подібне поняття між комоданами та функторами, чимось на зразок коплікативного функтора, і які його властивості?

FunctorsFunctorsApplicative functors???MonadsComonads

Оновлення: Мені також цікаво можливе використання такої концепції.


Ви впевнені, що не шукали комонів -> ??? -> Кофунктори?
Джосія

1
@josiah Ні, наскільки я знаю, комони - це функтори , а не кофунктори.
Петро Пудлак

1
Чи не ділиться той відсутній шматок?
Гас

Відповіді:


15

Поперше:

Будь-яка монада також є прикладним функціонером, а будь-який прикладний функтор - функтор.

Це вірно в контексті Хаскелла, але (читання Applicativeяк "сильний млявий моноїдальний функтор") взагалі не з досить тривіальної причини, що ви можете мати "прикладних" функторів між різними моноїдними категоріями, тоді як монади (і комонади) є ендофункторами .

Крім того, ототожнення Applicativeз сильними розслабленими моноїдними функторами злегка вводить в оману, тому що для обгрунтування назви (та підпису типу (<*>)) потрібен функтор між закритими моноїдними категоріями, що зберігає як моноїдну структуру, так і внутрішній хом . Це, правдоподібно, можна назвати "млявим замкнутим моноїдальним функтором", за винятком того, що функтор між моноїдальними закритими категоріями, що зберігає будь-яку властивість, зберігає інший очевидним чином . Оскільки Applicativeописуються лише ендофайнери на Hask, що зберігають моноїдну структуру (,), його екземпляри автоматично набувають безліч властивостей, включаючи їх силу , яку, таким чином, можна уникнути.

Очевидний зв'язок з Monad, мабуть, є артефактом імпліцитних обмежень у тому, що Applicativeзмушують збігатися аспекти їхніх моноїдних структур, щасливий збіг, який, на жаль, не переживає дуалізації.

Так само, як комонада на категорії - це монада на C o p , опіксальний моноїдний функтор C D - млявий моноїдальний функтор C o pD o p . Але H s до про р НЕ моноідальная закритий , і з- що не включає в себе функцію додатка навряд чи заслуговує назви. У будь-якому випадку, результат не був би надзвичайно цікавим:CCop CDCopDopHaskopApplicative

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

Натомість ми могли б уявити собі поняття "колакс-закритий функтор", який би виглядав набагато більше, Applicativeякби він існував. На жаль, взагалі не є (наскільки мені відомо) закритою категорією: в H a s k відповідає морфізмам b a в H a s k o p , але не працює як внутрішній hom там - тому що стрілки повернуті назад, потрібна буде якась функція, яку ми не можемо визначити загалом для H a s k .Haskopnewtype Op b a = Op (a -> b)HaskbaHaskopOp b aHask

Якщо ми просто зробимо вигляд, що "колективні закриті функтори" існували для , і, крім того, працювали так, як ми би наївно сподіваємось, що це буде, співавтор на цьому, мабуть, виглядатиме так:HaskApplicative

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)

Але це стикається з тими ж питаннями, що і вище, а саме, що не є закритою категорією. Якби це було, ми мали б певний тип таким чином, що ми могли б написати такі функції , як і і так далі , що на насправді працювали , як і очікувалося.Haskopb <~ acontracurry :: (Either c b <~ a) -> (c <~ (b <~ a))contraapply :: b -> Either a (a <~ b)

Якщо пам'ять слугує мені, перешкоди тут не характерні лише для Haskell, а швидше виникають з HaskCoApplicative

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


Порівнюючи свою відповідь на cstheory.stackexchange.com/a/22302/989 , дивно, що ви не дуалізуєте продукти до сум. Звичайно, ти маєш рацію, що у Hask немає категоричних сум; але якщо ви готові обмежитися категорією загальних програм (як, наприклад, в 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) показують, що прикладний функтор, також відомий як ідіома, є сильним млявим моноїдальним функтором . Ви шукаєте сильний моноїдний функтор колаксу, відомий також як сильний моноїдний функціонал опалаксу . Як згадувалося в коментарі, моноїдальний функтор оксала - це в'ялий моноїдний функтор між протилежними категоріями, що в кінцевому підсумку є комоноїдною версією млявого моноїдального функтора.

Намалюйте схеми, переверніть стрілки!

Мені доведеться витратити трохи часу на розробку деталей, щоб побачити, що це таке, і перевести це у поняття функціонального програмування.


Чомусь стандартним терміном здається, що це «моноїдальний функтор опала». Ідея - це в'ялий моноїдний функтор між протилежними категоріями, що в кінцевому підсумку є комоноїдною версією млявого моноїдального функтора. Використання "колакомоїдального колаксу" є або зайвим, або еквівалентним "млявим моноїдним".
CA McCann

Я переоцінив "спів". Я виправлю свою відповідь.
Дейв Кларк
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.