Read float or string from user input

Viewed 83

I want to be able to read numbers from console input, and store them into a list until the user types end, like this:

readN = readNumbers []    

readNumbers nums = do
      n <- readFloatOrString
      case n of
        <<number>> -> return readNumbers (nums ++ [n])
        "end" -> return nums

Is this doable without importing a library?

1 Answers

You should not read the value, or at least not immediately. You can first check if the line is "end", if so return the numbers, and otherwise continue reading:

import Text.Read(readMaybe)

readNumbers :: IO [Float]
readNumbers = do
      n <- getLine
      case (n, readMaybe n :: Maybe Float) of
        ("end", _) -> pure []
        (_, Just n) -> (n:) <$> readNumbers
        (_, Nothing) -> …

The … is the part that should handle the case if you did not pass a valid float number.

We thus can process a list with:

Prelude Text.Read> readNumbers 
1
4
end
[1.0,4.0]

(here the boldface part is user input).

Related