haskellinputoutputmonads# 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
readInt = do
line <- readLine
return (read line :: Int)
readLine :: IO String
readLine = do
c <- getChar
case c of
'\n' -> return []
_ -> do
cs <- readLine
return (c:cs)
```

So I just had to write the `adder`

function:

```
adder :: IO ()
adder = do
putStr "How many numbers? "
n <- readInt
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 ()
adder = do
putStr "How many numbers? "
n <- readInt
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)
adder :: IO ()
adder = do
putStr "How many numbers? "
ns <- readInt >>= (`replicateM` readInt)
putStrLn $ "The total is " ++ (show (sum ns))
```

as for `readInt`

, this can be implemented as:

```
readInt :: IO Int
readInt = readLn
```

- What is the proper way of wrapping an Int (not a general type) in another type if type safety is the only motive?
- What is the most practical way to express a dependency on a library for which we have a local git repository with some changes?
- Htmx POST to haskell servant handling optional field in FormUrlEncoded request
- Haskell fails to infer the return type of a monad after using the sequence operator
- Does extracting values from a multiple Value return in Haskell invoke the function more than once?
- How to specify c/c++ compiler on stack install command
- Why do I get "Unexpected reply type" from notify-send when using this Haskell notification server?
- Don't understand notation of morphisms in Monoid definition
- Foldln in haskell
- Is this property of a functor stronger than a monad?
- How to Instantiate a Custom Data Type with Record Syntax and Multiple Constructors
- How do I make a minimal working example for the a DBus server?
- Is it safe to downgrade Haskell stack version?
- Haskell, list of natural number
- unfamiliar syntax in Haskell / Clash function type signature
- foldM with monad State does not type check
- Why does my Runge-Kutta implementation oscillate to 0?
- How do I get the desired behavior in my TCP server?
- Why does the Haskell PVP describe new functions as non-breaking?
- How do I correctly use toLower in Haskell?
- How can I write a notification server in Haskell?
- Every Lens' is a Traversal'... how?
- How do I crate a value of type a{sv} for a call to org.freedesktop.Notifications.Notify via DBus?
- Web Scraping With Haskell
- Double exclamation marks in Haskell
- Haskell Servant POST FormUrlEncoded for (Vector String) field
- Confusion about list types in Haskell
- Idiomatic way to define new vs persisted types in Haskell
- Why does Cabal, unlike GHC, not automatically enable GeneralizedNewtypeDeriving if I explicitly enabled DerivingStrategies?
- Parsing inside `between` with Megaparsec