parce que j'ai trop simplifié dans mon Autre question avant, je voudrais donner un Exemple plus clair ici.
Comment puis-je gérer des situations où je dois vérifier les conditions de certian de manière séquentielle sans imbrication de plusieurs cas? Avec "manière séquentielle", je veux dire avoir une valeur (par exemple de STDIN), vérifier cette valeur pour une certaine condition et en fonction du résultat obtenant une autre valeur, etc. p>
Exemple: P>
sequen :: IO String
sequen = do
a <- getLine
case a of
"hi" -> do
putStrLn "hello!"
b <- getLine
case b of
"how are you?" -> do
putStrLn "fine, thanks"
return "nice conversation"
_ -> return "error 2"
_ -> return "error 1"
5 Réponses :
AVERTISSEMENT: Sonkell Newbie répondant à Haskell. P>
Vous pouvez éviter ce type d'escalier avec la monade peut-être. Bon exemple au début de Ce chapitre P>
Cependant, vous voudriez quelque chose de similaire avec une monadique soit (probablement il en existe un) car vous retournez des codes d'erreur. P>
L'idée de base étant qu'une fois que vous avez une erreur "gauche de 1", vous ferez un court-circuit toutes les étapes futures (en raison de l'évaluation paresseuse). P>
Ah, je vois que j'étais sur la bonne voie selon @gabriel ci-dessous.
À cause de l'évaluation paresseuse? Ou en raison de la définition de l'instance monad pour code>?
Bien sûr. Ceci est précisément ce que Le type de bloc intérieur est eithert code> a été fait. Vous pouvez l'obtenir à partir de contrôler.monad.trans.e code> dans le package eithert code>. eithert code> Aborte le bloc de code actuel chaque fois qu'il rencontre une instruction code> gauche code> et les personnes utilisent généralement pour indiquer les conditions d'erreur. p> eithert int io string code>. Lorsque vous RUNEITERTERTER CODE> IT, vous obtenez io (Soit String) code>. Le type gauche code> correspond au cas où il a échoué avec un gauche code> et la valeur code> droite code> signifie qu'il atteint avec succès la fin du bloc. p> p>
Impressionnant. Exactement ce que je voulais savoir. Merci!
Sur la note d'Eithert, j'ai écrit un article de blog sur ce qui a été assez bien reçu: ocharles.org.uk/blog/posts/2012-07-24-in-prise-freithert.h tml
@ochars j'ai lu cela il y a un moment et j'ai pensé que cela devrait être la solution à mon problème, mais je ne pouvais pas l'appliquer jusqu'à présent. Vous pouvez créer un lien vers cette question dans votre message :)
@Gabriel avez-vous l'intention d'Eithert de remplacer complètement les cas d'utilisation errortronomique? J'utilise Errort depuis longtemps, mais je trouve parfois gênant de déclarer l'instance d'erreur pour toutes mes classes d'exception.
J'aimerais vraiment eithert code> pour remplacer errort code> pour tous les cas d'utilisation possibles. Le problème est que Edward KMett et que j'ai du mal à convaincre Ross Patterson à (a) supprimer la contrainte d'erreur code> d'erreur code> à partir de ERRORT code> ou (b) Ajouter ESHERTERT code> à transformateurs code>. C'est la tenue pour le moment.
Puisque vous êtes nécessairement dans le Dans ce cas, vos erreurs sont simplement io code> monad, vous ferez mieux d'utiliser les fonctionnalités de gestion des erreurs code> monad au lieu d'empiler une erreur monade sur io code>. Il évite tout le lift lourde code> ing: String code> S, qui sont lancées par < Code> io code> 'S échoue code>, en tant que userError code>. Si vous souhaitez lancer un autre type, vous devrez utiliser lancer code> au lieu de échouer code>. P> p>
J'ai écrit une série de messages un moment de retour sur mes propres apprentissages du J'utilise les erreurs code> Erreurs CODE> Pour obtenir un tas de beaux aides à l'aide d'Eithert ( En extrayant votre Les conditions de défaillance potentielles dans leurs propres assistants, vous pouvez rendre la liste principale de votre code lu totalement séquentiellement séquentiellement, sans aucune déclaration de cas de vérification des résultats. P> à partir de ce poteau, vous pouvez voir comment le code> & eithert code> types. Vous pouvez le lire ici: http://watchrisearn.com/ Blog / 2013/12/01 / Travailler - entièrement-in-eithert / à gauche Code> et DROITE CODE> Fonctions, par exemple pour revenir aux versions soulevées de gauche code> et droit code>). p> runeithert code > La section est une partie de travail séquentielle, il se trouve que la mécanique de défaillance de eithert code>. Évidemment, ce code est équité à montrer comment maybet code> joue à l'intérieur de eithert code> aussi. En vrai code, ce serait juste l'histoire que vous vouliez dire, avec un seul gauche code> / droit code> à la fin. P>
Vieux exemple! Merci d'avoir souligné que vous pouvez mettre les cas dans des fonctions distinctes. Rend la fonction principale beaucoup plus agréable à lire.
à un moment donné Le package L'installation standard Haskell est livrée avec le (Notez que le plus susmentionné eithert code> a été obsolète (bien que Transformers - code> offre une API similaire). Heureusement, il y a une alternative à eithert code> qui ne nécessite même pas d'installer un package séparé. contrôle.monad.trans.except code> module (à partir du Transformers Code> Package, qui est fourni avec GHC), ce qui se comporte presque de manière identique à eithert code>. Le code résultant est presque em> identique au code dans réponse de Gabriella Gonzalez , mais en utilisant runexcept code> à la place de runeithert code> et jets code> au lieu de laissé code>. p> Transformers - code> est en fait une enveloppe pour sauf Code> Conçu pour fournir une compatibilité avec le code qui utilise toujours eithert code>.) p> p>