12
votes

Qu'est-ce qui est si spécial sur le mot-clé "retour"

Quand j'ai semblé comprendre quel retour est à Haskell, j'ai essayé de jouer avec différentes alternatives et il semble que le retour non seulement peut être utilisé n'importe où dans la chaîne monade, mais peut également être exclu complètement xxx Pré>

Même si j'élever retour dans mon instantanément, je n'obtiens que ... P>

*Main> JustG 9 >>= \y -> (JustG 11) >>= \x -> (finallyMyLastStepG y)
JustG 9


3 commentaires

retour n'est pas un mot-clé. Et oui, il ne contrôle pas le flux de contrôle comme le mot-clé du même nom ne fait que dans la plupart des langages de programmation impérative, de sorte que le retourner ... dans do {foo; revenir ...; quux} est redondant.


@delnan, le problème est quand je lisai tout sur Monads, "retour" à la dernière ligne ressemblait à l'exigence. Mais dans ma 3ème ligne, je l'ai remplacée par une création directe de valeur monadique et que le haskell est correct avec cela.


@Maksee: Avoir un retour à la dernière ligne n'est pas une exigence. Il arrive tellement que pour la monade peut-être, l'opération de liaison contient une construction d'une nouvelle monade simple. Ce n'est généralement pas le cas; Considérez, disons, l'identité monade. Il n'appelle pas retour sur n'importe quoi dans lier .


3 Réponses :


13
votes

Je soupçonne que vous êtes mal compris ce que "retour" signifie dans le contexte d'une monade à Haskell. Le retour est une fonction qui prend dans un a et renvoie un "CODE A " - c'est-à-dire l'instance la plus simple possible de la monade. Dans d'autres langues, il est souvent appelé unité . Ce n'est pas le "flux de contrôle" retour que vous voyez dans des langues similaires à C.

Donc dans votre exemple du peut-être monad, nous avons un retour défini comme une fonction Cela prend dans un A et renvoie un peut-être un : xxx

et qu'est-ce que cela fait? Si vous le donnez x , il vous donne le retour juste x : xxx

et maintenant vous pouvez utiliser retourner en tant que raccourci lorsque vous avez besoin de cette fonction, plutôt que d'écrire: xxx

Ça s'appelle retour car lorsque vous écrivez OUT MONADS IN DO NOTATIONED, il ressemble à ce que vous feriez dans une langue de type C.


7 commentaires

Ok, \ x -> (juste x) dans ma troisième ligne fait exactement la même chose, il renvoie la valeur monadique


Est-il appelé unité ? AFAIK unité comme nom de remplacement pour le tuple vide (ou plus abstraitement / généralement / correctement / correctement, le type avec une seule valeur).


@ERIC_LIPPERT, donc le "retour" est un sucre de syntaxe? Semble que personne ne mentionne jamais cela.


@Delnan: Oui, "unité" est souvent utilisée à ces fins.


@Maksee: retour est une exigence du motif monad. Je gère une série sur une douce introduction à Monads pour des programmeurs orientés objet sur mon blog en ce moment; Sur cela, je dis que je dis CreateSimplem au lieu de retour pour le garder clair. Vous voudrez peut-être vérifier. Ericlippert.com/category/monads , commencez par le bas.


retour n'est pas le sucre de syntaxe. C'est une fonction. Bien qu'un polymorphe.


Techniquement, juste seul est également un remplacement approprié pour (\ x-> juste x) car juste est une fonction ordinaire. génial de voir Eric Lippert répondant à une question Haskell.



37
votes

Alors qu'est-ce qui est si spécial sur le mot-clé de retour? p>

Premièrement, retour code> est pas em> un mot-clé à Haskell. C'est une fonction surchargée. P>

Son type est donné par: p> xxx pré>

de sorte que vous voyez que retour code> est une fonction que Compte tenu d'une valeur de type A code>, renvoie une nouvelle valeur de type mA code>, où m code> est un type d'instance de monad code>. Ces types comprennent: p>

  • monad [] code> li>
  • monad i0 code> li>
  • monad peut-être code> li>
  • monad sm code> li>
  • monad ((->) r) code> li>
  • monad (e) code> li>
  • monad (s) code> li> ul>

    et beaucoup plus d'ailleurs. Les cas de 'monad' devraient satisfaire les lois suivantes: p> xxx pré>

    La mise en oeuvre d'une fonction a -> m A code> est assez facile à deviner. Voici la définition des monades les plus courantes: p>

    listes em>: p> xxx pré>

    peut-être em> P>

    Prelude> do x <- return 1 ; y <- return 2 ; return (x + y) :: Maybe Int
    Just 3
    Prelude> do x <- Nothing  ; y <- return 2 ; return y
    Nothing
    


6 commentaires

Ok, je vois que l'application de "mot-clé" à "retour" est fausse, mais la plupart de ma question était de savoir si je devrais toujours l'utiliser ou que je puisse utiliser en toute sécurité l'autre façon de faire la même chose. En d'autres termes, voir que le même résultat peut être renvoyé plusieurs autres moyens, pourquoi devrais-je suivre la convention?


Donc, je peux remplacer votre dernier exemple avec do x <- 1); y <- (juste 2); (juste (x + y)) et obtenir le même résultat sans utiliser "retour"


@Maksee: Yup, ça fait la même chose.


@Maksee Il fait la même chose, mais il a une lacune importante: elle ne fonctionne que pour peut-être s. Si vous utilisez le retour, vous pouvez utiliser le même code pour n'importe quelle monade (essayez [], par exemple).


@MikehartL, génial, le même code que dans "Copy-Coller" fonctionne différemment en cours de contexte différent ou dans le même code que dans le corps de fonction étant différent de la nature polymorphe? Il vaut mieux être ce dernier :)


@Maksee Le même code que dans la définition d'une fonction polymorphe qui fonctionne pour des monades arbitraires. Ceci est essentiel pour les bibliothèques de Haskell. On ne pouvait pas définir les fonctions telles que mapm ou Séquence , qui fonctionne pour les monads arbitraires, sans retour - vous ne pouvez jamais les définir pour un seul Monad. Sans cette généralité, il n'y aurait pas de point à Monads, cependant!



2
votes

Mike Hartl Commentaire m'a conduit à la bonne direction, bien que n'était pas si formel, je ne fais que publier ma compréhension finale en tant que spécial sur l'opérateur "retour".

Toute classe de type répertorie l'opérateur qu'il prend en charge et il existe des fonctions qui ne peuvent fonctionner que dans ce contexte de classe (symbole de Constratints de classe imposée =>). Donc, par exemple, la signature du filtrage xxx

nous montre qu'il ne peut être utilisé que dans le contexte monadique. La magie est que, dans le corps, cette fonction est libre d'utiliser n'importe quel opérateur de la classe (>> = et de retour pour la monade) et si une instance (par exemple mon maybeg) n'a pas une méthode (retour dans mon cas), la fonction peut alors échouer. Ainsi, lorsque le retour est là xxx

et quand il est commenté (voir ma mise en œuvre de maybeg dans la question) xxx

Donc, une impythémicité de tout opérateur (le retour dans la monade) est requise si l'on prévoit d'utiliser l'instance avec des fonctions travaillant avec cette classe (monad dans ce cas) contrainte.

Je pense que mon malentendu initial était due au fait que la plupart des tutoriels expliquent des chaînes monadiques sans contexte polymorphe (ad hoc). Ce contexte à mon avis fait des monades plus puissantes et réutilisables.


1 commentaires

Même lorsque vous connaissez l'instance monad que vous utilisez, vous pouvez ne pas savoir comment il est implémenté, vous devez donc utiliser retour pour soulever une valeur. Par exemple, comment soulevez-vous une valeur dans io sans retour ?