Vous pouvez ajouter un guard
comme suggéré par Thomas M. Dubuisson:
date :: Parser (String, String, String)
date = do
year <- replicateM 4 digit
month <- replicateM 2 digit
day <- replicateM 2 digit
guard $ read month > 0 && read month <= 12 && read day > 0 && read day <= 31
return (year, month, day)
Cependant, cela se traduit par un mauvais message d'erreur:
λ> parse date "" "20161356"
Left (line 1, column 9):unknown parse error
Nous pouvons résoudre ce problème en combinant guard
avec <?>
pour fournir un meilleur message d'erreur:
date :: Parser (String, String, String)
date = do
year <- replicateM 4 digit
month <- replicateM 2 digit
guard (read month > 0 && read month <= 12) <?> "valid month (1–12)"
day <- replicateM 2 digit
guard (read day > 0 && read day <= 31) <?> "valid day (1–31)"
return (year, month, day)
Avec cette approche, vous obtenez un message d'erreur plus utile:
λ> parse date "" "20161356"
Left (line 1, column 7):
expecting valid month (1–12)
Comme une note de côté, je pense qu'il est précieuse pour valider (ou au moins vérification de la santé mentale) la date dans un analyseur-il veille à ce que la validation de la date se compose du reste de votre analyseur et du code de gestion des erreurs. Vous ne pouvez pas oublier de vérifier la date plus tard dans votre code et l'erreur est localisée correctement, ce qui est très utile si vous analysez des documents avec beaucoup de dates.
'guard $ mois> = 0 && mois <= 12'? –
'> = 1' peut-être? : D – ThreeFx
Side note 20160229 est valide tandis que 20000229 n'est pas, ne foget pas pour vérifier cela aussi – epsilonhalbe