Reputation: 957
I cannot compile the following code:
main = do
line <- getLine
putStrLn (work (toInt line) [0,0,0])
work n b = do
if n == 0
then
unwords (map show b)
else do
line <- getLine
work n-1 summ (map toInt . unwords line) b
toInt :: String -> Int
toInt b = read b
toInts a = map toInt a
summ [] [] = []
summ (x:xs) (y:ys) = (x+y) ++ (summ xs ys)
Here is the error:
src\Main.hs:28:21:
Couldn't match expected type `[t0]' with actual type `IO String'
In a stmt of a 'do' expression: line <- getLine
In the expression:
do { line <- getLine;
work n - 1 summ (map toInt . unwords line) b }
In the expression:
if n == 0 then
unwords (map show b)
else
do { line <- getLine;
work n - 1 summ (map toInt . unwords line) b }
What I expect from the program is to read
n
a1 b1 c1
a2 b2 c2
...
a_n b_n c_n
and output
sum(a) sum(b) sum(c)
Could You please explain why the fist occurence of getLine is OK, but the following is not?
EDIT1
I fixed the work function as follows:
work :: Int -> [Int] -> String
work n b = do
if n == 0
then
return $ unwords (map show b)
else do
line <- getLine
work (n-1) (summ toInts.words line b)
And the error is now:
src\Main.hs:27:13:
Couldn't match expected type `Char' with actual type `[Char]'
Expected type: String
Actual type: [String]
In the expression: return $ unwords (map show b)
In the expression:
if n == 0 then
return $ unwords (map show b)
else
do { line <- getLine;
work (n - 1) (summ toInts . words line b) }
EDIT2 Here is the final working prog:
main = do
line <- getLine
ans <- (work (toInt line) [0,0,0])
putStrLn ans
work 0 b = return $ unwords (map show b)
work n b = do
line <- getLine
work (n-1) $ zipWith (+) (map toInt (words line)) b
toInt b = read b::Int
Upvotes: 0
Views: 293
Reputation: 3927
It appears that work
isn't in the IO
monad: you can fix this by making the then
part of the if-statement read: return $ unwords (map show b)
.
Explicit type-signatures are an extremely helpful aid to Haskell programming: whilst you technically speaking don't need them, a very common work-flow is:
The version that matches the edit in the original question is:
work :: Int -> [Int] -> IO String
work n b = do
if n == 0
then
return $ unwords (map show b)
else do
line <- getLine
work (n-1) $ summ (map toInts $ words line) b
An improved variant is:
work :: Int -> [Int] -> IO String
work 0 bs = return . unwords $ map show bs
work n bs = do line <- getLine
work (n-1) $ summ (map toInts $ words line) b
Note also that your definition of summ
is incorrect as it uses ++
when it should use :
(and is in fact identical to zipWith (+)
).
Upvotes: 3
Reputation: 47052
You have
work n b = do
if n == 0
then
unwords (map show b)
else do
line <- getLine
work n-1 summ (map toInt . unwords line) b
The last line there should probably be
work (n-1) (summ (map toInt . unwords line) b)
Note the extra brackets.
There are probably other errors as well.
Upvotes: 0