Par contre, je me dis qu'il peut arriver qu'une opération map échoue
Ça dépend de ce que tu veux dire. Les fonctions Haskell sont pures (elles n’ont pas d’effet de bord), donc un cas comme celui plus au pour convertir une liste de chaînes de caractères en liste d’entier correspondant à leurs tailles pourra s’écrire :
> map length ["a", "aa", "aaa"]
[1,2,3]
Comme length est une fonction pure, elle n’échouera jamais, que son appel soit effectué via un map, ou en parallèle via un parMap.
Maintenant, tu peux vouloir utiliser des fonctions avec des effets de bord, ce qui correspond à la monade IO en Haskell. En imaginant une fonction length' qui peut échouer, une façon standard serait de renvoyer Nothing en cas d’erreur, mais on peut conserver l’entrée avec Left/Right. Le map devient alors un mapM dans la monade IO :
Tu peux remarquer que le code est quasiment identique (dans l‘interpréteur). Relancer le calcul pour les éléments pour lesquels la fonction a échoué se fera avec la même fonction mapM, et un simple encapsuleur pour length', ne ré-exécutant le code qu’en cas d’échec (pour le dernier élément dans l’exemple précédent).
Rappeler plusieurs fois la fonction encapsulée avec mapM relève de la simple politique du programme. Ce qu’on peut conclure, c’est qu’Haskell donne tous les outils pour exprimer ces concepts de façon très concise.
[^] # Re: C++ std::future
Posté par neil . En réponse à la dépêche Sortie du livre « Parallel and Concurrent Programming in Haskell ». Évalué à 2. Dernière modification le 28 juillet 2013 à 09:05.
Ça dépend de ce que tu veux dire. Les fonctions Haskell sont pures (elles n’ont pas d’effet de bord), donc un cas comme celui plus au pour convertir une liste de chaînes de caractères en liste d’entier correspondant à leurs tailles pourra s’écrire :
Comme
lengthest une fonction pure, elle n’échouera jamais, que son appel soit effectué via unmap, ou en parallèle via unparMap.Maintenant, tu peux vouloir utiliser des fonctions avec des effets de bord, ce qui correspond à la monade IO en Haskell. En imaginant une fonction
length'qui peut échouer, une façon standard serait de renvoyerNothingen cas d’erreur, mais on peut conserver l’entrée avecLeft/Right. Lemapdevient alors unmapMdans la monade IO :Tu peux remarquer que le code est quasiment identique (dans l‘interpréteur). Relancer le calcul pour les éléments pour lesquels la fonction a échoué se fera avec la même fonction
mapM, et un simple encapsuleur pourlength', ne ré-exécutant le code qu’en cas d’échec (pour le dernier élément dans l’exemple précédent).Où
wrapest définie comme :Rappeler plusieurs fois la fonction encapsulée avec
mapMrelève de la simple politique du programme. Ce qu’on peut conclure, c’est qu’Haskell donne tous les outils pour exprimer ces concepts de façon très concise.