Che cos'è una Comonad e come sono utili?

13

Recentemente ho rispolverato le mie conoscenze su come funzionano le Monade. Ho anche introdotto il concetto di 'Comonad' , che è descritto come il inverso doppio di un monade . Tuttavia, sono impossibile girarci intorno.

Per capire Monads, ho fatto la mia stessa analogia:

Monads can be seen as 'a blueprint to build conveyor belts of expressions'.

To define a new Monad(a new kind of conveyor-belt system) you need to define:

  1. A way to put something on a conveyor belt, e.g. 'start' a conveyor belt. (Known as unit or return)
  2. A way to connect a machine (an expression) that will be part of a conveyor belt to a conveyor belt. (Known as join or bind or >>=).

(There is a third operation that takes the current conveyor belt, throws its contents away and starts a new conveyor belt known as >>, but it is used very rarely.)

For the machines and conveyors to work properly together, you will need to make sure that:

  1. If you put something on a conveyor belt and pass it through a machine, the output should be the same as when you pass it through the machine manually. (Left Identity)
  2. If you want to put a conveyor-belt in-between an already existing conveyor belt, you should not end up with a conveyor belt that has a conveyor belt on top, but rather a single, longer conveyor belt. (Right Identity)
  3. It should not matter for the output if you manually use machine A, and then pass the result through the conveyor-connected B-C, or if you use conveyor-connected A-B and then pass the result manually through C. In other words: ((a >>= b) >>= c) should be the same as (a >>= (b >>= c)) (Associativity)

The most simple conveyor-belt would be the one that just takes the input and always continues on to the next expression. This is what a 'pipeline' is.

Another possibility, is to only let it go through the next machine if some condition is met for the value. This means that if at some of the expressions in-between, the value changes to something that is no longer allowed, then the rest of the expressions will be skipped. This is what the 'Maybe' monad does in Haskell.

You can also do other fancy conditional copy/change rules on the values before or after you pass them to a machine. An example: Parsers (Here, if an expression returns a 'failure' result, the value from before the expression is used as output).

Ovviamente l'analogia non è perfetta, ma spero che dia una rappresentazione chiara di come funzionano le monadi.

Tuttavia, sto avendo molti problemi a trasformare questa analogia in testa per capire le Comonad. So dalle piccole quantità di informazioni che ho trovato su Internet che una Comonad definisce:

  • extract , che è una specie di reverse di return , cioè prende un valore out di una Comonad.
  • duplicate , che è un po 'l'inverso di join , cioè crea due Comonade da una sola.

Ma come può una Comonad essere istanziata se siamo solo in grado di estrarre da loro o duplicarli? E come possono effettivamente essere utilizzati? Ho visto questo bellissimo progetto e ne parliamo (che purtroppo ho capito molto poco di), ma non sono sicuro di quale parte della funzionalità sia fornita esattamente da una Comonad.

Che cos'è una Comonad? Per cosa sono utili? Come possono essere usati? Sono commestibili?

    
posta Qqwy 16.06.2016 - 13:30
fonte

2 risposte

8

Una comonade è, proprio come una monade, una struttura matematica nella teoria delle categorie. Il co-prefisso è molto comune lì a denotare "inversioni" come le hai definite (anche se non credo che i puri matematici concordino sulla scelta della parola).

Nella teoria delle categorie ci sono categories , che mettono brevemente una raccolta di objects (di qualsiasi tipo o natura, la struttura interna è irrilevante) e alcuni arrows tra questi oggetti. Perché qualcosa sia una categoria, le frecce devono seguire alcune leggi (identità sinistra / destra e associatività), ma qui non è molto importante.

Ora, la teoria delle categorie è sia molto astratta / difficile da trovare e vasta. Ci vuole un sacco di tempo per passare attraverso tutto (e non l'ho studiato formalmente, conosco solo alcune nozioni di base), ma c'è una nozione usata che si chiama dual . Fondamentalmente, per ogni categoria puoi costruire un opposite category semplicemente facendo la stessa cosa ma "invertendo tutte le frecce". Questa è una definizione molto ingenua, ma è difficile cercare di sintetizzare. Il doppio di qualcosa in una categoria C è fondamentalmente la stessa cosa nella categoria opposta C_op (avere ancora un mal di testa?)

Ad ogni modo, se hai una monade su qualche categoria (e una categoria può essere ad esempio una categoria in cui gli oggetti sono tipi in qualche linguaggio di programmazione e le frecce sono funzioni tra i tipi), allora una comonad è fondamentalmente la stessa cosa , solo tu hai invertito tutte le frecce (un po 'come invertire le firme delle funzioni in questo caso).

Una descrizione più "pratica" (sebbene non SUPER-disponibile) può essere trovata in questo discussione tra Erik Meijer e Brian Beckman in cui stanno discutendo la nozione di dualità e come Erik ha fatto "invertire le frecce" per IEnumerable<T> in C # durante la creazione del framework reattivo e IObservable<T> (che per quanto posso dire, e Sono felice di essere corretto, fondamentalmente è una lista di istanza di Comonad).

Un altro esempio pratico di comonad menzionato nel video è il tipo Task<T> in .NET, dove Task<U> ContinueWith<U>(Func<Task<T>, U>) sarebbe il doppio di bind (o SelectMany come viene chiamato in C #)

    
risposta data 18.06.2016 - 21:58
fonte
1

Dalla mia piccola comprensione, una comonade è una macchina Rube Goldberg per fare post-documenti:

link

... scusa, non ho potuto resistere.

    
risposta data 20.06.2016 - 14:44
fonte

Leggi altre domande sui tag