Can I use "let" inside "do"?

Viewed 89

This simple program prints the sum and product of a list of numbers from an input file.

main :: IO ()
main = do
  text <- readFile "./input.txt"
  print $ sum [read line | line <- lines text]
  print $ product [read line | line <- lines text]

{-

Example input:
1
2
3
4

Example output:
10
24

-}

It would be nice to avoid repeating [read line | line <- lines text]. If I extract the function printSumAndProduct, I can use a let expression to do this:

main :: IO ()
main = do
  text <- readFile "./input.txt"
  printSumAndProduct text

printSumAndProduct :: String -> IO ()
printSumAndProduct text =
  let numbers = [read line | line <- lines text]
  in do
    print $ sum numbers
    print $ product numbers

However, I would prefer to just have one function, main. Is it possible to do this without having a separate function printSumAndProduct?

Here's what I've tried:

main :: IO ()
main = do
  text <- readFile "./input.txt"
  let numbers = [read line | line <- lines text]
  in do
    print $ sum numbers
    print $ product numbers

But this is a syntax error:

main.hs:5:3: error: parse error on input ‘in’
1 Answers
Related