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:
- Un moyen de mettre quelque chose sur un tapis roulant, par exemple «démarrer» un tapis roulant. (Connu comme
unit
oureturn
)- Un moyen de connecter une machine (une expression) qui fera partie d'un tapis roulant à un tapis roulant. (Connu comme
join
oubind
ou>>=
).(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:
- 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)
- 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é)
- 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 dereturn
, qui est, il faut une valeur hors d'un Comonad.duplicate
, qui est en quelque sorte l'inverse dejoin
, 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?
IO
monade est le système d'exécution Haskell, qui invoquemain
. Il y a aussiunsafePerformIO
, bien sûr. Si vous voulez considérer laMaybe
monade comme ayant une «machine au bout du tapis roulant», vous pouvez l'utilisermaybe
.cobind
applications, il doit y avoir une fonction qui fait quelque chose d'utile avec la représentation interne de votre comonad.Réponses:
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 deobjects
(de tout type ou nature, la structure interne n'a pas d'importance) et certainsarrows
entre 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 un
dual
. Fondamentalement, pour chaque catégorie, vous pouvez construire unopposite category
en 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 etIObservable<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 debind
(ouSelectMany
comme on l'appelle en C #)la source
De ma petite compréhension, une comonad est une machine Rube Goldberg pour faire des post-docs:
http://www.willamette.edu/~fruehr/haskell/evolution.html
... désolé, je n'ai pas pu y résister.
la source