Случайно, что бесплатный foo - это самая простая вещь, которая удовлетворяет всем законам «foo». То есть он полностью соответствует законам, необходимым для того, чтобы быть обманщиком, и ничего лишнего.
Забывчивый функтор - это тот, кто «забывает» часть структуры при переходе из одной категории в другую.
Данные функторы F : D -> C
, и G : C -> D
, мы говорим F -| G
, F
присоединены слева G
или G
присоединены справа к F
всякий раз, когда все a, b: F a -> b
изоморфно a -> G b
, где стрелки приходят из соответствующих категорий.
Формально свободный функтор оставляется присоединенным к забывчивому функтору.
Свободный моноид
Давайте начнем с более простого примера - свободного моноида.
Возьмите моноид, который определяется некоторым набором носителей T
, бинарная функция помять пару элементов вместе f :: T → T → T
, и unit :: T
, таким образом, что у вас есть ассоциативный закон, и закон идентичности: f(unit,x) = x = f(x,unit)
.
Вы можете сделать функтор U
из категории моноидов (где стрелки являются моноидными гомоморфизмами, то есть они гарантируют, что они сопоставляются unit
с unit
другим моноидом, и что вы можете создавать до или после сопоставления с другим моноидом без изменения значения) в категорию наборов (где стрелки - просто функциональные стрелки), которые «забывают» об операции и unit
, и просто дают вам набор несущих.
Затем вы можете определить функтор F
из категории множеств обратно в категорию моноидов, оставленных присоединенными к этому функтору. Этот функтор является функтором, который отображает набор a
в моноид [a]
, где unit = []
и mappend = (++)
.
Итак, чтобы рассмотреть наш пример до сих пор, в псевдо-Haskell:
U : Mon → Set -- is our forgetful functor
U (a,mappend,mempty) = a
F : Set → Mon -- is our free functor
F a = ([a],(++),[])
Затем, чтобы показать, что F
это бесплатно, мы должны продемонстрировать, что он оставлен присоединенным к U
забывчивому функтору, то есть, как мы упоминали выше, нам нужно показать, что
F a → b
изоморфен a → U b
помните, что цель F
находится в категории Mon
моноидов, где стрелки являются моноидными гомоморфизмами, поэтому нам нужно показать, что гомоидизм моноидов из [a] → b
может быть точно описан функцией из a → b
.
В Haskell мы называем ту сторону этого, которая живет в Set
(то есть, Hask
категория типов Haskell, которую мы притворяемся, это Set), просто foldMap
, которая, когда специализируется от Data.Foldable
Lists, имеет тип Monoid m => (a → m) → [a] → m
.
Из этого следствия вытекают последствия. Примечательно, что если вы забудете, то создайте бесплатно, а затем снова забудете, это так же, как вы однажды забыли, и мы можем использовать это для создания монадического соединения. так как UFUF
~ U(FUF)
~ UF
, и мы можем перейти в тождестве моноидного гомоморфизма [a]
с [a]
помощью изоморфизма , который определяет наше примыкание, получаю , что список изоморфизмомом [a] → [a]
является функцией типа a -> [a]
, и это просто вернуться к спискам.
Вы можете составить все это более непосредственно, описав список в следующих терминах:
newtype List a = List (forall b. Monoid b => (a -> b) -> b)
Свободная Монада
Так что же такое свободная монада ?
Ну, мы делаем то же самое, что и раньше, мы начинаем с забывчивого функтора U из категории монад, где стрелки - гомоморфизмы монад, в категорию эндофункторов, где стрелки - естественные преобразования, и мы ищем функтор, который оставляется присоединенным. к тому, что.
Итак, как это относится к понятию свободной монады, как это обычно используется?
Знание того, что что-то является свободной монадой, Free f
говорит вам, что дать гомоморфизм монады из Free f -> m
, это то же самое (изоморфно), что и дать естественное преобразование (гомоморфизм функторов) из f -> m
. Помните, что он F a -> b
должен быть изоморфным для того, a -> U b
чтобы F оставался присоединенным к U. Здесь монады отображаются на функторы.
F, по крайней мере, изоморфен Free
типу, который я использую в моем free
пакете при взломе.
Мы могли бы также построить его в более тесной аналогии с приведенным выше кодом для свободного списка, определив
class Algebra f x where
phi :: f x -> x
newtype Free f a = Free (forall x. Algebra f x => (a -> x) -> x)
Кофейные Комонады
Мы можем построить нечто подобное, взглянув на правое сопряжение с забывчивым функтором, предполагая, что оно существует. Свободный функтор просто / прямо присоединен / к забывчивому функтору, и симметрично знать, что что-то является свободной комонадой, - это то же самое, что знать, что давать гомоморфизм комонады из w -> Cofree f
- это то же самое, что давать естественное преобразование из w -> f
.