Um foo livre passa a ser a coisa mais simples que satisfaz todas as leis 'foo'. Isto é, satisfaz exatamente as leis necessárias para ser um foo e nada extra.
Um functor esquecido é aquele que "esquece" parte da estrutura à medida que passa de uma categoria para outra.
Dado functors F : D -> C, e G : C -> D, dizemos F -| G, Fé deixado adjacente a G, ou Gé adjacente a todo momento em Fque todos a, b: F a -> bé isomórfico para a -> G b, onde as setas vêm das categorias apropriadas.
Formalmente, um functor livre fica adjacente a um functor esquecido.
O Monóide Livre
Vamos começar com um exemplo mais simples, o monóide livre.
Dê uma monoid, que é definida por um conjunto transportador T, uma função binário para esmagar um par de elementos juntos f :: T → T → T, e uma unit :: T, de modo que você tem uma lei associativa, e uma lei de identidade: f(unit,x) = x = f(x,unit).
Você pode fazer um functor Uda categoria de monoids (onde flechas são homomorphisms monoid, isto é, garantir que eles mapear unita unitdo outro monoid, e que você pode compor antes ou após o mapeamento para o outro monoid sem alterar o significado) à categoria de conjuntos (onde as setas são apenas setas funcionais) que 'esquecem' da operação e unit, e apenas fornecem o conjunto da transportadora.
Em seguida, você pode definir um functor Fda categoria de conjuntos para a categoria de monoides que fica adjacente a esse functor. Esse functor é o functor que mapeia um conjunto apara o monóide [a], onde unit = [], e mappend = (++).
Então, para revisar nosso exemplo até agora, em pseudo-Haskell:
U : Mon → Set -- is our forgetful functor
U (a,mappend,mempty) = a
F : Set → Mon -- is our free functor
F a = ([a],(++),[])
Então, para mostrar Fé gratuito, precisamos demonstrar que ele fica adjacente a Uum functor esquecido, ou seja, como mencionamos acima, precisamos mostrar que
F a → b é isomórfico para a → U b
Agora, lembre-se de que o alvo de Festá na categoria Monde monóides, onde as setas são homomorfismos monóides; portanto, precisamos mostrar que um homomorfismo monóide de [a] → bpode ser descrito precisamente por uma função de a → b.
Em Haskell, chamamos o lado disso que vive em Set(er, Haska categoria de tipos de Haskell que pretendemos ser Set), just foldMap, que quando especializada de Data.Foldablepara Lists tem tipo Monoid m => (a → m) → [a] → m.
Há conseqüências que se seguem, sendo uma adjunção. Notavelmente, se você esquecer, construa gratuitamente, e esqueça novamente, é como você esqueceu uma vez, e podemos usar isso para criar a junção monádica. desde UFUF~ U(FUF)~ UF, e podemos passar o homomorfismo monóide de identidade de [a]para [a]o isomorfismo que define nossa adjunção, entender que um isomorfismo de lista [a] → [a]é uma função do tipo a -> [a], e isso é apenas um retorno para listas.
Você pode compor tudo isso mais diretamente, descrevendo uma lista nestes termos com:
newtype List a = List (forall b. Monoid b => (a -> b) -> b)
The Free Monad
Então, o que é uma Mônada Livre ?
Bem, fazemos o mesmo que fizemos antes, começamos com um esquecido functor U da categoria de mônadas, onde as flechas são mônadas homomorfismos, até uma categoria de endofuncionadores, onde as flechas são transformações naturais, e procuramos um functor que fica ao lado para isso.
Então, como isso se relaciona com a noção de mônada livre, como costuma ser usada?
Saber que algo é uma mônada livre Free f, diz a você que fornecer uma homônima de mônada Free f -> mé a mesma coisa (isomórfica a) que fornecer uma transformação natural (de um homomorfismo de functor) f -> m. Lembre-se de que F a -> bdeve ser isomórfico para a -> U bque F seja deixado adjacente a U. U aqui mapeou mônadas para functores.
F é pelo menos isomorfo ao Freetipo que eu uso no meu freepacote sobre hackage.
Também podemos construí-lo em analogia mais rigorosa ao código acima para a lista livre, definindo
class Algebra f x where
phi :: f x -> x
newtype Free f a = Free (forall x. Algebra f x => (a -> x) -> x)
Comonadas Cofree
Podemos construir algo semelhante, observando o anexo correto de um functor esquecido, assumindo que ele existe. Um functor co-livre é simplesmente / diretamente adjunto / a um functor esquecido e, por simetria, saber que algo é uma comonada livre é o mesmo que saber que dar homomorfismo a uma comonada w -> Cofree fé o mesmo que dar uma transformação natural w -> f.