D'accord, première règle de gestion des erreurs dans Haskell: ne jamais utilisererror .
C'est juste terrible à tous points de vue. Il existe purement comme un acte d'histoire et le fait que Prelude l'utilise est terrible. Ne l'utilisez pas.
Le seul moment imaginable que vous pourriez utiliser est quand quelque chose est si terrible en interne que quelque chose doit être incorrect avec le tissu même de la réalité, rendant ainsi le résultat de votre programme théorique.
Maintenant , la question devient Maybevs Either. Maybeest bien adapté à quelque chose comme head, qui peut ou non retourner une valeur mais il n'y a qu'une seule raison possible d'échouer. Nothingdit quelque chose comme "il s'est cassé, et vous savez déjà pourquoi". Certains diraient que cela indique une fonction partielle.
La forme la plus robuste de gestion des erreurs est Either+ une erreur ADT.
Par exemple, dans l'un de mes compilateurs de loisirs, j'ai quelque chose comme
data CompilerError = ParserError ParserError
| TCError TCError
...
| ImpossibleError String
data ParserError = ParserError (Int, Int) String
data TCError = CouldntUnify Ty Ty
| MissingDefinition Name
| InfiniteType Ty
...
type ErrorM m = ExceptT CompilerError m -- from MTL
Maintenant, je définis un tas de types d'erreur, en les imbriquant de sorte que j'ai une glorieuse erreur de niveau supérieur. Cela peut être une erreur de n'importe quelle étape de la compilation ou un ImpossibleError, ce qui signifie un bogue du compilateur.
Chacun de ces types d'erreur essaie de conserver le plus d'informations possible le plus longtemps possible pour une jolie impression ou une autre analyse. Plus important encore, en n'ayant pas de chaîne, je peux tester que l'exécution d'un programme de type incorrect via le vérificateur de type génère en fait une erreur d'unification! Une fois que quelque chose est un String, c'est parti pour toujours et toute information qu'il contient est opaque pour le compilateur / tests, donc ce Either Stringn'est pas génial non plus.
Enfin, j'emballe ce type dans ExceptTun nouveau transformateur monade de MTL. C'est essentiellement EitherTet est livré avec un joli lot de fonctions pour lancer et attraper des erreurs de manière pure et agréable.
Enfin, il convient de mentionner que Haskell a les mécanismes pour prendre en charge la gestion des exceptions comme le font d'autres langues, sauf que la capture d'une exception existe IO. Je sais que certaines personnes aiment les utiliser pour IOdes applications lourdes où tout pourrait potentiellement échouer, mais si rarement qu'elles n'aiment pas y penser. Que vous utilisiez ces exceptions impures ou simplement, ExceptT Error IOc'est vraiment une question de goût. Personnellement, j'opte pour ExceptTcar j'aime qu'on me rappelle les risques d'échec.
En résumé,
Maybe - Je peux échouer d'une manière évidente
Either CustomType - Je peux échouer, et je vais te dire ce qui s'est passé
IO+ exceptions - j'échoue parfois. Consultez mes documents pour voir ce que je jette quand je le fais
error - Je te déteste aussi, utilisateur
headoulastsemblent utilisererror, alors je me demandais si c'était vraiment une bonne façon de faire les choses et il me manquait juste quelque chose. Cela répond à cette question. :)