简体   繁体   中英

Using readMaybe to read list of natural numbers

I am using this function to read list of natural numbers from string in the following format: [1, 2, 3] :

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

Right now it only works for integers - what would be the correct way to check whether the numbers are natural? Should I modify the Just l clause to check whether all numbers are >=0 ? Is it a good idea to return Nothing from such nested Just clause?

You could use do -notation and guard from Control.Monad to avoid the excessive pattern matching:

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

Well, if you're going to use return anyway to invoke the monad instance for Maybe , then I think I'd probably write:

import Text.Read
import Control.Monad

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

which is a more idiomatic application of the Maybe monad. Whether it's clearer than the explicit pattern-matching (and monad-free) alternative:

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

is probably a matter of opinion and intended audience.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM