• [^] # Re: C++ std::future

    Posté par . 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.

    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 :

    > resultat <- mapM length' ["a", "aa", "aaa"]
    [Right 1,Right 2,Left "aaa"]
    

    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).

    > mapM (wrap length') resultat
    [Right 1,Right 2,Right 3]
    

    wrap est définie comme :

    wrap f (Left s) = f s
    wrap _ r = r
    

    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.