Y a-t-il une bonne raison pour laquelle le type de Prelude.read est
read :: Read a => String -> a
plutôt que de renvoyer une valeur Maybe
?
read :: Read a => String -> Maybe a
Étant donné que la chaîne peut ne pas être Haskell analysable, cette dernière ne serait-elle pas plus naturelle?
Ou même un Either String a
, où Left
contiendrait la chaîne d'origine si elle n'était pas analysée, et Right
le résultat si c'était le cas?
Modifier:
Je n'essaie pas d'amener les autres à écrire un wrapper correspondant pour moi. Je cherche simplement à m'assurer qu'il est sécuritaire de le faire.
Edit : Depuis GHC 7.6, readMaybe
est disponible dans le Text.Read
module dans le package de base, avec readEither
: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Text-Read.html#v : readMaybe
Grande question! Le type de lecture lui-même ne changera pas de sitôt car cela casserait beaucoup de choses. Cependant, il y a devrait être une fonction maybeRead
.
Pourquoi n'y a-t-il pas? La réponse est "l'inertie". Il y avait un discussion en '08 qui a été déraillé par une discussion sur "échouer".
La bonne nouvelle est que les gens étaient suffisamment convaincus pour commencer à s'éloigner de l'échec dans les bibliothèques. La mauvaise nouvelle est que la proposition s'est perdue dans le mélange. Il y a devrait être une telle fonction, bien qu'elle soit facile à écrire (et il y a des millions de versions très similaires flottant autour de nombreuses bases de code).
Voir aussi cette discussion .
Personnellement, j'utilise la version du paquet sûr .
Ouais, ce serait pratique avec une fonction de lecture qui retourne peut-être. Vous pouvez en créer un vous-même:
readMaybe :: (Read a) => String -> Maybe a
readMaybe s = case reads s of
[(x, "")] -> Just x
_ -> Nothing
En dehors de l'inertie et/ou de l'évolution des idées, une autre raison pourrait être qu'il est esthétiquement agréable d'avoir une fonction qui peut agir comme une sorte d'inverse de show
. Autrement dit, vous voulez que read . show
est l'identité (pour les types qui sont une instance de Show
et Read
) et que show . read
est l'identité sur la plage de show
(c'est-à-dire show . read . show == show
)
Avoir un Maybe
dans le type de read
rompt la symétrie avec show :: a -> String
.
Comme l'a souligné @augustss, vous pouvez créer votre propre fonction de lecture sécurisée. Cependant, son readMaybe
n'est pas complètement cohérent avec read, car il n'ignore pas les espaces à la fin d'une chaîne. (J'ai fait cette erreur une fois, je ne me souviens plus du contexte)
En regardant le définition de read dans le rapport Haskell 98 , nous pouvons le modifier pour implémenter un readMaybe
qui est parfaitement cohérent avec read
, et ce n'est pas trop gênant car toutes les fonctions dont il dépend sont définies dans le Prélude:
readMaybe :: (Read a) => String -> Maybe a
readMaybe s = case [x | (x,t) <- reads s, ("","") <- Lex t] of
[x] -> Just x
_ -> Nothing
Cette fonction (appelée readMaybe
) est maintenant dans le prélude Haskell! (À partir de la base actuelle - 4.6)