6

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 Answer 1

6

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).

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! what is pure for?
@tacofisher: it "wraps" a value, here in an IO, so pure x, results in an IO that "returns" x.
@duplode Very nice..!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.