Haskell: inline auxiliary function into do block

Working through Programming in Haskell (Second Edition) by Graham Hutton, I just managed to solve exercise 10.5 (page 138). The task is to write a function `adder :: IO ()` that reads `n` numbers (to be defined interactively), sums them up, and prints the result, like so:

``````> adder
How many numbers? 3
5
4
6
The total is 15
``````

The functions `readInt` and `readLine` are already given as:

``````readInt :: IO Int

c <- getChar
case c of
'\n' -> return []
_ -> do
return (c:cs)
``````

So I just had to write the `adder` function:

``````adder :: IO ()
putStr "How many numbers? "
ns <- sequence [readInt | _ <- [1..n]]
sum <- sumUp ns
putStr \$ "The total is " ++ (show sum) ++ "\n"

sumUp :: [Int] -> IO Int
sumUp xs = return \$ foldl (+) 0 xs
``````

I'm almost happy with my solution, but I'd just like to inline the `sumUp` function. However, I have no idea how to do it.

How can I inline a `[a] -> IO a` function into a `do` block?

Solution

• There is no need to use `return` here, we can use `sum :: (Foldable f, Num a) => f a -> a` to sum up the numbers:

``````adder :: IO ()
putStr "How many numbers? "
ns <- sequence [readInt | _ <- [1 .. n]]
putStr \$ "The total is " ++ (show (sum ns)) ++ "\n"``````

We can also repeat `readInt` through `replicateM :: Applicative m => Int -> m a -> m [a]`:

``````import Control.Monad(replicateM)

as for `readInt`, this can be implemented as:
``````readInt :: IO Int