11
votes

Dérivation de la monade libre

contrôler.monad.free implémente une monade gratuite comme: xxx

J'ai beaucoup de difficulté à comprendre le deuxième aller ligne, surtout dans le contexte des descriptions de Qu'est-ce qu'une monade gratuite est . Can Somenoe s'il vous plaît décrire comment cela fonctionne et pourquoi il fait Free Fa une monade gratuite?


3 commentaires

<$> == fmap , peut-être que cela le rend plus clair. Ceci est plus ou moins la seule mise en œuvre possible.


@Niklasb. peut <$> être utilisé à la fois préfixe et infixe?


@groovy: Ouais, comme n'importe quelle fonction: (+ 1) <$> [1,2,3] == (<$>) (+1) [1,2,3] == fmap (+ 1) [1,2,3] == (+1) `fmap` [1,2,3]


3 Réponses :


14
votes

À ce stade, vous faites simplement gratuit code> un foncteur plutôt qu'une monade. Bien sûr, être une monade, il doit s'agir également d'un foncteur!

Je pense qu'il serait un peu plus facile de penser si nous renommerions le constructeur code> gratuit (code> pour éviter toute confusion: P>

data Free f a = Pure a | Wrap (f (Free f a))


0 commentaires

1
votes

Depuis que je suis confondu moi-même, je réponds avec une question ... Cela pourrait-il être une substitution correcte (s'appuyant sur la clarification globale de Tikhon)? xxx


6 commentaires

Une monade gratuite est 0 ou plus wrap s se terminant dans un pure . FMAP F Applique la fonction f à la valeur stockée dans la finale pure .


@Gabrielgonzalez Merci, c'est une explication très concise et claire. Puis-je vous demander si la substitution que j'ai écrite a du sens?


Ouais, sauf pour une faute de frappe. Il devrait être enveloppement (F (pur (ga))) au lieu de wrap (F (pure g a)) . Autre que cela vous avez raison.


Bonjour Groovy, comment avez-vous eu de wrap (fmap (fmap g) (fmap g) (F F (Free FA))) à Wrap (F (FMAP G (Free FA))) ?


Bonjour Groovy, comment avez-vous eu de wrap (fmap (fmap g) (fmap g) (F F (Free FA))) à Wrap (F (FMAP G (Free FA))) ?


@ Me2 pense au type de fmap - donné une fonction (a -> b) et un foncteur fa , fmap applique la fonction à A , entraînant fb . Une étape avant f b pourrait être écrit comme f ((a -> b) a) . Depuis à l'intérieur de l'enveloppe, nous avons une expression qui ressemble à fmap (une fonction) (FA) , nous pouvons déplacer la fonction à l'intérieur du fonctionnement pour obtenir wrap (f ((fmap g) )) . Notre A dans ce cas est (Free Fa) et la fonction est (fmap g) . En raison de la nature de la FMAP, nous pouvons éliminer ces parenthèses intérieures pour obtenir wrap (fmap ga)) , où a est (Free fa) . Cela a-t-il du sens?



7
votes

Pour vous dire la vérité, je trouve généralement que cela ne trouve généralement pas pas em> pour lire le code dans ces fonctions simples, mais plutôt pour lire les em> types em> puis écrivez la fonction moi même. Pensez-y comme un casse-tête. Vous essayez de construire ceci: xxx pré>

alors comment le faisons-nous? Eh bien, prenons le constructeur pure code> d'abord: p> xxx pré>

avec les deux commentaires de type et connaissant le type de pur code>, vous devriez voir la solution immédiatement: p> xxx pré>

maintenant le deuxième cas: p> xxx pré>

Eh bien, puisque f code> est un document code>, nous pouvons réellement utiliser mapfree code> pour appliquer mapfree f code> sur le composant interne de f (FA) Code>. Nous obtenons donc: p> xxx pré>

maintenant, à l'aide de cette définition comme référence Foncteur F => Foncteur (Free f) code> instance, nous obtenons: P >

instance Functor f => Functor (Free f) where
  fmap f (Pure a) = Pure (f a)
  fmap f (Free fa) = Free (fmap (fmap f) fa)


0 commentaires