web-dev-qa-db-fra.com

Pourquoi Haskell's Prelude.read ne renvoie-t-il pas un peut-être?

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.

101
Bilal Barakat

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 .

99
sclv

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
29
augustss

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.

14
yatima2975

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
11
lpsmith

Cette fonction (appelée readMaybe ) est maintenant dans le prélude Haskell! (À partir de la base actuelle - 4.6)

7
amindfv