7
votes

Conversion `Do` Notation` Addstuff` à `>> =`

Décrochez un haskell présente le Fonction Fonction: < Pré> xxx

sont les types de A , b et retour (A + B) Tous Int -> int ? Je pense que, mais je ne sais pas comment lier joue un rôle.

J'ai essayé de le mettre en œuvre en utilisant >> = , mais Je ne sais pas comment le compléter (par conséquent ... ). xxx

donnez-moi un indice pour le compléter, ainsi que Modifiez ma compréhension de la version de notation do .

Si je comprends, le ... doit inclure un type de int -> int . Dans la version do , je pourrais utiliser A et b , mais je ne sais pas comment les ajouter avec le >> = version.


2 commentaires

Vous devriez rechercher l'application. Je ne peux pas vérifier si (+) <$> (* 2) <*> (+10) est correct, mais je suis sûr que twsttuff peut être écrit dans un style d'application.


@Kevinmeredith: Le message suivant explique le désupération de do de manière succincte Stackoverflow.com/a/16726740/ 917635 . Pourrait être utile.


3 Réponses :


4
votes

comme une règle approximative si vous souhaitez désinvérer manuellement la notation de Do-Notation, effacez d'abord le faire code> en haut et retournez la flèche de connexion ( à gauche -Avez-le-côté à un (>> =) code> à droite avec la variable de gauche en tant que variable Lambda à droite. Donc:

{-# LANGUAGE ScopedTypeVariables #-}

import Control.Monad.Instances

addStuff :: Int -> Int
addStuff = do
    (a :: Int) <- (*2)
    (b :: Int) <- (+10)
    (return (a+b)) :: Int -> Int


1 commentaires

Une note: la première règle de réécriture ne détient que dans le cas (certes fréquemment) lorsque A est un motif qui ne peut pas échouer. Sinon, la règle est un peu plus compliquée, voir Le rapport de langue



7
votes

Lorsque vous travaillez avec le lecteur monade (A.k.a. la fonction monade), vous avez le type a -> b , qui peut être réécrit comme (->) A B . L'instance de monad réelle ici est xxx

remarque que pendant >> = , le type est xxx

lequel peut être réécrit comme xxx

ou même xxx

afin que vous puissiez voir, quel >> = < / code> prend une seule entrée, s'applique qu'en f , puis appliquez ce résultat à g pour produire une nouvelle fonction r -> b . Donc, pour votre exemple, vous pouvez utiliser: xxx

et donc towstFF '10 == 30 , car il effectue le calcul (10 * 2) + (10) . Remarque Comment 10 est alimenté à la fois sur (* 2) et (+) et le résultat de (10 * 2) < / code> est envoyé à (+) aussi. Cela pourrait rendre les choses un peu plus clairs pour le voir comme xxx

et c'est le résultat serait xxx

Qu'est-ce que cela essentiellement est en train de prendre l'argument sur test "avant", il a été appliqué, l'alimentant à chacune des fonctions du côté droit du <- S, puis combinant Cela entraîne le retour .


Alors, comment pouvez-vous écrire cela sans la notation? Vous pouvez faire quelque chose comme xxx

lequel, certes, n'est pas très lisible, même avec le formatage, mais le gist est fondamentalement que r est alimenté pour Chaque fonction intermédiaire, qui produit un résultat et quelques expressions de Lambda imbriquées plus tard, vous retournerez plus tard les trois de ces résultats dans un tuple.

avec un peu de simplification, vous pouvez également faire chacun de ces lambdas imbriquées dans Deux arguments Lambdas: xxx

J'ai également remplacé le dernier \ z -> retour (x, y, z) avec son équivalent \ z -> const (x, y, z) => \ zr -> const (x, y, z) r , il suffit donc de tous avoir la même forme. < / p>


0 commentaires

1
votes

Merci à Bheklilr. J'ai écrit mon propre code.

addStuff :: Int -> Int
addStuff = (\r -> r * 2) >>= (\x ->
           (\r -> r + 10) >>= (\y ->
           return (x + y)))


0 commentaires