Reputation: 142
I am trying to write a simple function which reads in one line at a time (which I know will be integers) and then stores them in to a list. For the life of me however, it seems like the list comes out to empty.
import System.IO
import Control.Monad
type Int2 = [Int]
valueTab = [] :: [Int]
app [ ] list = list
app (h:t) list = h:(app t list)
main :: IO ()
main = do
hSetBuffering stdout NoBuffering -- DO NOT REMOVE
-- Auto-generated code below aims at helping you parse
-- the standard input according to the problem statement.
input_line <- getLine
let n = read input_line :: Int
let value = [] :: [Int]
replicateM n $ do
input_line <- getLine
let pi = read input_line :: Int
hPutStrLn stderr (show input_line)
hPutStrLn stderr (show valueTab)
return $ app valueTab [pi]
-- hPutStrLn stderr "Debug messages..."
-- Write answer to stdout
--putStrLn input_line
return ()
So when I run this with 8 6 4 3 all on their own lines, It prints 6, [], 4, [], 3 [].
Is this a problem with my printing, with my list declaration, with the way that I store them or? I have both value and valueTab to check whether it was a scope problem.
Note: The code is boilerplate code on a coding website that tests it on it's platform. Assume replicateM is just a loop that runs through the code x number of times.
Upvotes: 0
Views: 1410
Reputation: 51129
It looks like you're doing a problem on codinggame.com. Other coding sites seem to do a better job with their Haskell templates, particularly for beginner exercises -- the template usually takes care of all the input and output, and you just need to supply the missing pure function. In contrast, codinggame.com's Haskell templates seem to assume the beginner has a pretty firm grasp of the IO monad, and leave out a lot of essential details (e.g., the fact that the result of the replicateM
action should actually be bound to a variable) which you're expected to fill in.
The replicateM
call in the original template probably looked something like:
replicateM n $ do
input_line <- getLine
let pi = read input_line :: Int -- maybe this line was there, maybe not
return ()
This expression creates a composite IO action that, when executed, will repeat the following subaction n
times:
input_line
pi
(though this is never done because pi
isn't used)()
) as the result of the subactionThe value of the composite action is then a list of the values returned by the subactions. Since those were all units, the final value of the composite action is a list [(),(),()...()]
, with one ()
for each line read. However, because the value of this composite action is never bound to a variable (i.e., because there's no result <- ...
before the replicateM
expression), this list is thrown away.
So, this template provides a needlessly verbose method of reading n
lines of input and doing nothing with them.
Fortunately, all you need to do to make this template do something useful is to have the subaction return a value that's useful (e.g., the integer pi
) which will cause the composite action to return a list of the integers read, and then make sure you bind the resulting list to a variable using the <-
notation.
In other words, you want to write:
main = do
...
pis <- replicateM n $ do
input_line <- getLine
let pi = read input_line :: Int
return pi
hPutStrLn stderr (show pis)
You won't need the helper function app
, and you won't need to pre-declare a list valueTab
to contain the result. The result is automatically produced by replicateM
, and you just need to name it so you can use it.
The complete working program will look like:
import System.IO
import Control.Monad
type Int2 = [Int]
main :: IO ()
main = do
hSetBuffering stdout NoBuffering -- DO NOT REMOVE
-- Auto-generated code below aims at helping you parse
-- the standard input according to the problem statement.
input_line <- getLine
let n = read input_line :: Int
let value = [] :: [Int]
pis <- replicateM n $ do
input_line <- getLine
let pi = read input_line :: Int
return pi
hPutStrLn stderr (show pis)
-- hPutStrLn stderr "Debug messages..."
-- Write answer to stdout
return ()
Upvotes: 1