Dans ce cas, Maybe
peut ne pas suffire: Vous avez trois conditions à se soucier:
- L'utilisateur est entré rien
- L'entrée de l'utilisateur était valide
- La saisie de l'utilisateur était impossible
Ce type de données et la fonction expriment ceci directement:
data Input a = NoInput | Input a | BadInput String
deriving (Eq, Show)
input :: (Read a) => String -> Input a
input "" = NoInput
input s =
case filter (null.snd) (reads s) of
((a,_):_) -> Input a
otherwise -> BadInput s
Notez que plutôt que d'utiliser la fonction incomplète read
, il utilise reads
qui ne sera pas erreur sur l'entrée qui ne peut pas être converti. reads
a une interface un peu maladroite, hélas, donc je finis presque toujours par l'emballer dans une fonction qui renvoie Maybe a
ou quelque chose comme ça ici.
Exemple d'utilisation:
> input "42" :: Input Int
Input 42
> input "cat" :: Input Int
BadInput "cat"
> input "" :: Input Int
NoInput
je coder votre fonction yearFilter
comme ceci:
yearFilter :: Maybe Int -> Int -> Bool
yearFilter Nothing _ = True
yearFilter (Just x) y = x == objectYear y
Ensuite, je poignée d'entrée utilisateur comme:
inputToMaybe :: Input a -> Maybe a
inputToMaybe (Input a) = Just a
inputToMaybe _ = Nothing
do
a <- input `fmap` getLine
case a of
BadInput s -> putStrLn ("Didn't understand " ++ show s)
otherwise -> ... yearFilter (inputToMaybe a) ....
NB : J'ai nettoyé le code dans yearFilter
un peu: pas besoin d'utiliser des gardes pour produire un booléen à partir d'un test - juste retourner le test, l'application de fonction (objectYear
) se lie plus étroitement que les opérateurs (==
) parenthèse enlevé, remplacé les noms des entrées inutilisées par _
.
D'accord, je l'avoue, je ne peux pas me aider .... Je l'ai réécrite yearFilter
encore une fois, cette fois-ci que je serais enclin à écrire:
yearFilter :: Maybe Int -> Int -> Bool
yearFilter x y = maybe True (== objectYear y) x
Apprendre Maybe
et maybe
était la première chose à propos de Haskell qui m'a vraiment fait aimer la langue.
S'il vous plaît, n'enseignez pas les personnes 'longueur x == 0'. La façon idiomatique et performante d'écrire ce test est «null x». –
Quant à être idiomatique, point pris. Compte tenu de la définition de «longueur», je ne peux pas croire qu'il y aurait une différence dans perf. En tout cas, je suis un peu surpris que quelqu'un ait ressenti le besoin de voter. –
"length" marchera jusqu'à la fin de la chaîne afin de trouver la longueur, et si cette chaîne est 400203209 caractères, vous avez un problème de performance. "null" fonctionnera à temps constant, car il suffit de voir si au moins un élément est là. – LukeN