Recentemente, venho divulgando meu conhecimento sobre como as mônadas funcionam. Também fui apresentado ao conceito de 'Comonad' , descrito como o dual inverso de uma mônada . No entanto, sou impossível envolvê-lo.
Para entender as Mônadas, fiz a própria analogia:
Mônadas podem ser vistas como "um plano para construir correias transportadoras de expressões".
Para definir um novo Monad (um novo tipo de sistema de correia transportadora), é necessário definir:
- Uma maneira de colocar algo em uma correia transportadora, por exemplo, 'iniciar' uma correia transportadora. (Conhecido como
unit
oureturn
)- Uma maneira de conectar uma máquina (uma expressão) que fará parte de uma correia transportadora a uma correia transportadora. (Conhecido como
join
oubind
ou>>=
).(Existe uma terceira operação que pega a correia transportadora atual, joga seu conteúdo fora e inicia uma nova correia transportadora conhecida como
>>
, mas é usada muito raramente.)Para que as máquinas e os transportadores funcionem corretamente juntos, você precisará garantir que:
- Se você colocar algo em uma correia transportadora e passá-lo através de uma máquina, a saída deve ser a mesma de quando você passa manualmente pela máquina. (Identidade Esquerda)
- Se você deseja colocar uma correia transportadora entre uma correia transportadora já existente, não deve acabar com uma correia transportadora que tenha uma correia transportadora no topo, mas sim uma correia transportadora única e mais longa. (Identidade correta)
- Não deve importar para a saída se você usar manualmente a máquina A e depois passar o resultado pelo BC conectado ao transportador, ou se você usar o AB conectado ao transportador e depois passar o resultado manualmente através de C. Em outras palavras: ((a >> = b) >> = c) deve ser o mesmo que (a >> = (b >> = c)) (Associatividade)
A correia transportadora mais simples seria aquela que apenas recebe a entrada e continua sempre na próxima expressão. Isto é o que é um "pipeline".
Outra possibilidade é deixá-lo passar pela próxima máquina se alguma condição for atendida para o valor. Isso significa que, se em algumas expressões intermediárias o valor mudar para algo que não é mais permitido, o restante das expressões será ignorado. É isso que a mônada 'Talvez' faz em Haskell.
Você também pode executar outras regras de cópia / alteração condicionais sofisticadas nos valores antes ou depois de passá-las para uma máquina. Um exemplo: Analisadores (Aqui, se uma expressão retornar um resultado de 'falha', o valor anterior à expressão será usado como saída).
Claro que a analogia não é perfeita, mas espero que dê uma boa representação de como as mônadas funcionam.
No entanto, estou tendo muitos problemas para mudar essa analogia para entender as Comonadas. Sei pelas pequenas quantidades de informações que encontrei na internet que uma Comonad define:
extract
, Que é uma espécie de reversoreturn
, ou seja, ele tem um valor fora de um Comonad.duplicate
, que é o inverso dejoin
, ou seja, cria duas comonadas a partir de uma única.
Mas como uma Comonad pode ser instanciada se somos capazes de extraí-las ou duplicá-las? E como eles podem realmente ser usados? Eu já vi esse projeto incrível e a conversa sobre ele (do qual, infelizmente, compreendi muito pouco), mas não tenho certeza de que parte da funcionalidade é fornecida exatamente por uma Comonad.
O que é uma Comonad? Para que eles são úteis? Como eles podem ser usados? Eles são comestíveis?
IO
mônada é o sistema de tempo de execução Haskell, que invoca main
. Há também unsafePerformIO
, é claro. Se você quiser pensar na Maybe
mônada como tendo uma "máquina no final da correia transportadora", poderá usar maybe
.
cobind
aplicativos, deve haver alguma função que faça algo útil na representação interna de sua comonada.