Number Guessing Game in Haskell I've been learning a lot about functional programming lately and I've recently started learning Haskell to which I'm very new.

I've written a simple number guessing game and I would like to have feedback on what is good or bad about my code and how it could be improved.

#!/usr/bin/env runhaskell

import Text.Printf (printf)
import System.Random (randomRIO)

smallest = 1 :: Integer
biggest = 100 :: Integer

main :: IO ()
main = do
  secret &lt;- randomRIO (smallest, biggest) :: IO Integer
  printf "Find the number between %d and %d.\n" smallest biggest
  loop secret 1 where
    loop :: Integer -&gt; Integer -&gt; IO ()
    loop secret tries = do
      guess &lt;- readLn :: IO Integer
      case compare guess secret of
        LT -&gt; do
          putStrLn "Too small!"
          loop secret $ succ tries
        GT -&gt; do
          putStrLn "Too big!"
          loop secret $ succ tries
        EQ -&gt; do
          printf "You found the number in %d tries!\n" tries
Changing the where to a let allows you to skip passing the secret. Passing guesses in and messages out purifies the control flow part of the program. zip [1..] makes clear: The number of tries during each step does not depend on the control flow. interact, lines and foldr replace the recursion. (Recursion is too powerful for brains to handle in general, so we should avoid it when we have a simpler tool.) Your mileage may vary on any of these suggestions.

secret &lt;- randomRIO (smallest, biggest) :: IO Integer
let foo :: (Integer, Integer) -&gt; String -&gt; String
    foo (tries, guess) = case compare guess secret of
      LT -&gt; (++) "Too small!\n"
      GT -&gt; (++) "Too big!\n"
      EQ -&gt; const $ printf "You found the number in %d tries!\n" tries
printf "Find the number between %d and %d.\n" smallest biggest
interact $ foldr foo undefined . zip [1..] . map read . lines