IO is how Haskell performs side effects — reading files, printing output, making network calls. It's a monad that sequences side effects while keeping the rest of your code pure.
do notation
HASKELL
main :: IO ()
main = do
putStrLn "What is your name?"
name <- getLine
let greeting = "Hello, " ++ name ++ "!"
putStrLn greetingThe do notation chains IO actions sequentially. Each <- extracts
the result from an IO action.
Putting and getting
HASKELL
putStrLn "Hello!" -- print with newline
putStr "No newline" -- print without newline
putChar 'A' -- print one character
name <- getLine -- read a line from stdin
-- ⚠️ getLine is unsafe — use readMaybe for numbersFile IO
HASKELL
import System.IO
import System.Directory
-- Read entire file
contents <- readFile "data.txt"
putStrLn contents
-- Write file (overwrites)
writeFile "output.txt" "Hello, Nepal!\n"
-- Append to file
appendFile "log.txt" "New entry\n"
-- With handle (more control)
handle <- openFile "data.txt" ReadMode
contents <- hGetContents handle
putStrLn contents
hClose handleSafer input
HASKELL
import Text.Read (readMaybe)
main :: IO ()
main = do
putStr "Enter your age: "
input <- getLine
case readMaybe input :: Maybe Int of
Just age -> putStrLn $ "You are " ++ show age ++ " years old."
Nothing -> putStrLn "That's not a valid number."The IO type is a type
HASKELL
-- IO is a type — functions returning IO a are actions, not values
greet :: IO ()
greet = putStrLn "Hello!"
-- do notation desugars to >>= (bind)
greet = putStrLn "Hello!" >> putStrLn "World!"
-- Or with explicit bind
greet = putStrLn "Hello!" >>= \_ -> putStrLn "World!"Tips
- Use
donotation for readability — it's syntactic sugar. IOis a type — functions returningIO aare actions, not pure values.- Use
readMaybeorreadsfor safe parsing of user input. - Haskell's purity means all side effects are explicit in the type system.
🎉 You have completed the Haskell course!