Haskell method for user accepting user input the number of times entered?

I'm just starting to learn haskell, and this is a completely different way of thinking than what I'm used to (C style languages).

In any case, for one problem, I am working on the fact that I need to get user input. It will be presented in the form

2 10 20 

eg. The format is the first line that indicates the number of lines. My first thought was that I would read the first line and then run the loop. This is Haskell! As far as I know, loops are impossible.

My next thought was that I would use the first line of input to populate the list with the other n numbers that follow. I have no idea how to do this. I am here because I’m not even sure what I will look for to understand this.

Thanks in advance for showing me a haskell way of doing this. It is still difficult, but I hear rave reviews from people who are "enlightened", so I believe that this can not stop myself from learning a language.

Here is the code that will run once just fine, but should run once for each of the lines with two by n following the first line.

 ln = (-1)^n/(2*(fromIntegral n)+1) am = sum [ln | n <- [0..(m-1)]] main = do b <- readLn print (ab) 

(In addition, I would like to hear if there are other improvements that I could make to my code, but in this particular case, it is for competition to solve the problem with the least number of characters. I do not want to get more specific information if others people are trying to find the answer to the same problem.)

EDIT: Thanks for the answers. In the end, I got what behaved the way I wanted it. I put the code below for posterity. Unfortunately, even though he passed the test tests with flying colors, the actual data they tested was different, and all they tell me is that I got a β€œwrong answer”. This code "works" but does not give you the correct answer.

 import Control.Monad ln = (-1)^n/(2*(fromIntegral n)+1) am = sum [ln | n <- [0..(m-1)]] main = do b <- readLn s <- replicateM b readLn mapM_ print [ac | c <- s] 
+8
haskell
source share
4 answers

First of all, you can get hung up on haskell. This happens all the time. You simply do not have syntax constructs for it, since there is no need for them.

In most cases, general purpose shared libraries are placed in libraries. In this case, the loop you need is in the standard libraries in the Control.Monad module. It was called replicateM . It has a signature like Monad m => Int -> ma -> m [a] . To specialize this signature for your case, it will have type Int -> IO Int -> IO [Int] . The first argument is the number of cycles. The second is the IO action to run in each cycle. The result of the function is an IO action that creates a list of inputs.

So, if you added inputs <- replicateM b readLn to the do block, it would put a list called inputs in the scope containing the values ​​from the input lines b following the first. Then you can map the solution function along these lines.

+10
source share

Carl's solution will work, but it is somewhat opaque. If you want to write this down, you can do something like this:

 readLines :: Int -> IO [Int] readLines 0 = return [] readLines n = do x <- fmap read getLine rest <- readLines (n-1) return $ x : rest readSomeNumberOfLines :: IO [Int] readSomeNumberOfLines = do n <- fmap read getLine readLines n 

What you do here with readLines is that you basically define the obvious base case (to read 0 things, just give an empty list) and the recursive case (read n things, read one, then read the other n-1 things , then combine them together).

+6
source share

I'm not sure what exactly you want to do, but to read the integer n and then the next n lines as integers, you can do something like:

 import Control.Monad -- read n, then sum integers read from the next n lines test = do n <- readLn xs <- replicateM n readLn return $ sum xs 

return $ sum xs at the end of the course is not essential - if it was not there, you will need an explicit type signature for test .

If you do not understand any of these functions, just hoogle them.

+2
source share

You can create readInput n , where n is the number of lines to read. A call recursively subtracts 1 from n each time. I am also a Haskell noob, so this is not the best approach. It should work anyway.

+1
source share

All Articles