MadeleineG
MadeleineG

Reputation: 31

Haskell- Read in user input number string and add them

I asked a question earlier and was left with more questions than answers.

I want to be able to do the following:Enter number of integers in a list followed by the number list.

Examples

4 1 2 3 4

OR

8 1 2 3 4 5 6 7 8

Right now I have the following code that is not working.

import Control.Monad


readLn = do
    putStrLn "Enter how many numbers:" -- clearer
    num<-getLine
    numbers<- replicateM num action
    putStrLn("Enter a number: ")
    numberString <- getLine
    return (read numberString :: Int)
    -- here we have numbers :: [Int]

Upvotes: 0

Views: 448

Answers (1)

chepner
chepner

Reputation: 532418

If you want a single line of input, it doesn't need to include the number of numbers, because you'll just split the line on whitespace to get your list.

foo :: IO [Int]
foo = do
   putStr "Enter your numbers, separated by whitespace (e.g. 4 5 3 2): "
   line <- getLine
   return $ map read (words line)

words splits an input like 2 3 4 5 into the list ["2", "3", "4", "5"].

If you want to control how many numbers are entered, with a separate prompt for each number, then you need replicateM:

-- No error handling or line editing, for simplicity
foo' :: IO [Int]
foo' = do
    putStr "How many numbers?: "
    n <- readLn
    replicateM n $ do
      putStr "Enter a number: "
      readLn

readLn is equivalent to fmap read getLine; you get a line of input, calling read on the resulting string.

replicateM takes an IO action, defined by the nested do block, as its second argument. You were passing an undefined variable action. That action produces an IO Int value, which replicateM repeats n times an combines the resulting IO Int values into a single IO [Int] value. (Which is the difference between replicateM and replicate, which would have produced a list of actions, [IO Int].)


Because foo and foo' are both declared to have type IO [Int], the compiler can infer the proper specific types for the uses of read and readLn.

Upvotes: 1

Related Questions