You are trying to add Int with IO Int in (x+sumInts).
Let's take this step by step:
getInt return an actions that when it's executed returns an "Int" and you execute it using <- :
x<-getInt
That means x have type Int.
In expression (x+sumInts) you use + which have a type of:
(+) :: Num a => a -> a -> a
Haskell interfer the type and replace a with the type of x, which means + will have type of:
(+) :: Int -> Int -> Int
and will expect as second parameter an Int.
You are providing as the second parameter sumInts which have a type IO Int and that's why you have that error couldn't match expected type Int with actual type IO Int.
To make it works you have to "get out" the value from IO action using <- like this:
sumInts :: IO Int
sumInts = do
x<-getInt
if x==0
then return 0
else do
rest <- sumInts
return (x+rest)
Another approach to solve ths, in a more readable, is using Applicative:
import Control.Applicative
getInt :: IO Int
getInt = do
s <- getLine
return (read s)
sumInts :: IO Int
sumInts = do
x<-getInt
if x==0 then return 0 else (x+) <$> sumInts
The <$> function takes a function (in our case x+) an apply it on value inside an Applicative Functor (IO is instance of Applicative and Functor) and return that Functor with computation applied.
Type of <$> is:
> :t (<$>)
(<$>) :: Functor f => (a -> b) -> f a -> f b
and for IO this will be :
(<$>) :: (a -> b) -> IO a -> IO b
(<$>) :: (Int -> Int) -> IO Int -> IO Int -- If we consider that a is an Int