Вільна 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
(er, Hask
категорія типів Haskell, на яку ми робимо вигляд, що встановлена), як раз foldMap
, яка, коли спеціалізується Data.Foldable
на списках, має тип 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. 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)
Cofree Comonads
Ми можемо побудувати щось подібне, подивившись праворуч на спокійний функтор, припустивши, що воно існує. Безфункціональний функтор - це просто / правильний примикання / до забудькуватого функтора, і за симетрією знати щось є кофрі-комода - це те саме, що знати, що давати гомоморфізм комонаду w -> Cofree f
- це те саме, що давати природну трансформацію w -> f
.