2017-05-28 2 views
1

J'utilise cette fonction pour lire la liste des nombres naturels de chaîne dans le format suivant: [1, 2, 3]:aide readMaybe à lire la liste des nombres naturels

readMaybeIntList :: String -> Maybe [Int] 
readMaybeIntList line = case readMaybe line of 
          Just l -> return l 
          Nothing -> Nothing 

En ce moment, il ne fonctionne que pour les entiers - quelle serait la manière correcte de vérifier si les nombres sont naturels? Dois-je modifier la clause Just l pour vérifier si tous les numéros sont >=0? Est-ce une bonne idée de retourner Nothing de telle clause imbriquée Just?

+1

pas une réponse très intéressante, mais je dirais oui aux deux questions que vous avez soulevées – hao

+0

Vous pouvez utiliser quelque chose comme 'Just l | all (> = 0) l -> ... ' – chi

+2

Votre instruction case est équivalente à' readMaybe line' de la même façon que si b alors vrai else false est équivalent à 'b'. –

Répondre

1

Eh bien, si vous allez utiliser return de toute façon d'invoquer l'instance monade pour Maybe, je pense Je serais probablement écrire:

import Text.Read 
import Control.Monad 

readMaybeNatList :: String -> Maybe [Int] 
readMaybeNatList line = do 
    ns <- readMaybe line 
    guard $ all (>=0) ns 
    return ns 

qui est une application plus idiomatiques du Maybe monade. Que ce soit plus clair que le modèle de correspondance explicite (et sans monade) alternatif:

readMaybeNatList' :: String -> Maybe [Int] 
readMaybeNatList' line = 
    case readMaybe line of 
    Just ns | all (>=0) ns -> Just ns 
    _ -> Nothing 

est probablement une question d'opinion et le public visé.

1

Vous pouvez utiliser do -notation et guard de Control.Monad pour éviter la mise en correspondance de motif excessif:

import Text.Read 
import Control.Monad 


readMaybeNatural :: String -> Maybe Int 
readMaybeNatural str = do 
    n <- readMaybe str 
    guard $ n >= 0 
    return n 


readMaybeNaturals :: String -> Maybe [Int] 
readMaybeNaturals = 
    sequence . map readMaybeNatural . words 
+0

Aussi, 'séquence. map f' = 'traverse f' –

+0

celui que j'oublie toujours, merci de le signaler! –