Случайно, что бесплатный 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.FoldableLists, имеет тип 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.