0

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]
3
  • 5
    Possible duplicate of How to read/ add/ print a number string in Haskell Commented Nov 30, 2018 at 20:48
  • @Rainbacon That was the OP's earlier question. Commented Nov 30, 2018 at 20:49
  • @chepner yes, and this is the exact same question. If the OP doesn't understand the answers they got on the other question, they should comment on the answers they received asking for clarification rather than asking a new question Commented Nov 30, 2018 at 20:50

1 Answer 1

1

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.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.