Qu'est-ce qu'un Comonad et comment sont-ils utiles?

16

Récemment, j'ai épousseté mes connaissances sur le fonctionnement des Monades. J'ai également été initié au concept de 'Comonad' , qui est décrit comme le dual inverse d'une monade . Cependant, je suis impossible d'envelopper ma tête autour d'elle.

Pour comprendre les Monades, je me suis fait l'analogie:

Les monades peuvent être considérées comme «un modèle pour construire des bandes transporteuses d'expressions».

Pour définir une nouvelle Monade (un nouveau type de système de convoyeur à bande), vous devez définir:

  1. Un moyen de mettre quelque chose sur un tapis roulant, par exemple «démarrer» un tapis roulant. (Connu comme unitou return)
  2. Un moyen de connecter une machine (une expression) qui fera partie d'un tapis roulant à un tapis roulant. (Connu comme joinou bindou >>=).

(Il y a une troisième opération qui prend le tapis roulant actuel, jette son contenu et démarre un nouveau tapis roulant appelé >>, mais il est utilisé très rarement.)

Pour que les machines et les convoyeurs fonctionnent correctement ensemble, vous devez vous assurer que:

  1. Si vous placez quelque chose sur un tapis roulant et le passez dans une machine, la sortie doit être la même que lorsque vous la passez manuellement dans la machine. (Identité de gauche)
  2. Si vous voulez placer une bande transporteuse entre une bande transporteuse déjà existante, vous ne devriez pas vous retrouver avec une bande transporteuse qui a une bande transporteuse sur le dessus, mais plutôt une bande transporteuse unique et plus longue. (Bonne identité)
  3. Cela ne devrait pas avoir d'importance pour la sortie si vous utilisez manuellement la machine A, puis passez le résultat via le BC connecté au convoyeur, ou si vous utilisez AB connecté au convoyeur et passez ensuite le résultat manuellement via C.En d'autres termes: ((a >> = b) >> = c) doit être identique à (a >> = (b >> = c)) (associativité)

La bande transporteuse la plus simple serait celle qui prend juste l'entrée et continue toujours à l'expression suivante. Voilà ce qu'est un «pipeline».

Une autre possibilité consiste à ne laisser passer la machine suivante que si une condition est remplie pour la valeur. Cela signifie que si au niveau de certaines expressions intermédiaires, la valeur devient quelque chose qui n'est plus autorisé, le reste des expressions sera ignoré. C'est ce que fait la monade «Peut-être» à Haskell.

Vous pouvez également effectuer d'autres règles de copie / modification conditionnelles de fantaisie sur les valeurs avant ou après leur transmission à une machine. Un exemple: analyseurs (ici, si une expression renvoie un résultat «échec», la valeur d' avant l'expression est utilisée en sortie).

Bien sûr, l'analogie n'est pas parfaite, mais j'espère qu'elle donne une bonne représentation du fonctionnement des monades.

Cependant, j'ai beaucoup de mal à renverser cette analogie pour comprendre les Comonads. Je sais d'après les petites quantités d'informations que j'ai trouvées sur Internet qu'un Comonad définit:

  • extract, Qui est en quelque sorte l'inverse de return, qui est, il faut une valeur hors d'un Comonad.
  • duplicate, qui est en quelque sorte l'inverse de join, c'est-à-dire qu'il crée deux Comonades à partir d'une seule.

Mais comment une Comonad peut-elle être instanciée si nous ne pouvons en extraire ou les dupliquer? Et comment peuvent-ils réellement être utilisés? J'ai vu ce projet très étonnant et les discussions à ce sujet (que j'ai malheureusement très peu compris), mais je ne sais pas exactement quelle partie des fonctionnalités est fournie par une Comonad.

Qu'est-ce qu'une Comonad? À quoi servent-ils? Comment peuvent-ils être utilisés? Sont-ils comestibles?

Qqwy
la source
2
"Comment une Comonad peut-elle être instanciée si nous ne pouvons les extraire ou les dupliquer?" - Je vais répondre à votre question par une question: comment une Monade peut-elle être consommée si vous ne pouvez y ajouter que des valeurs et séquencer les calculs?
Benjamin Hodgson
1
La "machine au bout de la bande transporteuse" (à part: je ne trouve pas les analogies très utiles quand on parle de monades) de la IOmonade est le système d'exécution Haskell, qui invoque main. Il y a aussi unsafePerformIO, bien sûr. Si vous voulez considérer la Maybemonade comme ayant une «machine au bout du tapis roulant», vous pouvez l'utiliser maybe.
Benjamin Hodgson
1
Mais, en retournant votre explication, lorsque vous voulez produire une valeur comonadique au début d'une chaîne d' cobindapplications, il doit y avoir une fonction qui fait quelque chose d'utile avec la représentation interne de votre comonad.
Benjamin Hodgson
2
Une instance spécifique de comonad ou monad peut clairement avoir plus de fonctionnalités que nécessaire juste pour implémenter les classes de types
jk.
2
Non pas que cela va être utile si vous n'abordez pas cette question du côté de la catégorie théorique / mathématique, mais je voulais souligner qu'une comonade n'est pas l'inverse mais plutôt le duel d'une monade.
Jörg W Mittag

Réponses:

11

Une comonade est, tout comme une monade, une structure mathématique dans la théorie des catégories. Le co-préfixe y est très courant pour désigner les "inverses" comme vous le dites (bien que je ne pense pas que les mathématiciens purs soient d'accord sur le choix du mot).

Dans la théorie des catégories, il y a categories , qui sont brièvement mis une collection de objects(de tout type ou nature, la structure interne n'a pas d'importance) et certains arrowsentre ces objets. Pour que quelque chose soit une catégorie, les flèches doivent suivre certaines lois (identité gauche / droite et associativité), mais ce n'est pas vraiment important ici.

Maintenant, la théorie des catégories est à la fois très abstraite / difficile à comprendre et vaste. Il faut beaucoup de temps pour passer par tout cela (et je ne l'ai pas étudié de manière formelle, je ne connais que quelques notions de base), mais il y a une notion utilisée qui s'appelle undual . Fondamentalement, pour chaque catégorie, vous pouvez construire un opposite categoryen faisant simplement la même chose mais en "inversant toutes les flèches". Il s'agit d'une définition très naïve, mais il est difficile d'essayer de résumer. Le double de quelque chose dans une catégorie C est fondamentalement la même chose dans la catégorie opposée C_op (vous avez encore mal à la tête?)

Quoi qu'il en soit, si vous avez une monade sur une catégorie (et une catégorie peut par exemple être une catégorie où les objets sont des types dans un langage de programmation et les flèches sont des fonctions entre les types), alors une comonad est fondamentalement la même chose, seulement vous 'ai inversé toutes les flèches (un peu comme inverser les signatures de fonction dans ce cas).

Une description plus "pratique" (bien que pas SUPER pratique) peut être trouvée dans cette discussion entre Erik Meijer et Brian Beckman où ils discutent de la notion de dualité et comment Erik a fait "inverser les flèches" pour IEnumerable<T>en C # lorsque créer le cadre réactif et IObservable<T>(qui pour autant que je sache, et je suis heureux d'être corrigé, est essentiellement une instance de liste comonad).

Un autre exemple pratique de comonads mentionné dans la vidéo est le Task<T>type dans .NET, où Task<U> ContinueWith<U>(Func<Task<T>, U>)serait le dual de bind(ou SelectManycomme on l'appelle en C #)

Sara
la source