A visual journey through pure functional programming.
quicksort :: Ord a => [a] -> [a]
quicksort [] = []
quicksort (x:xs) =
quicksort smaller ++ [x] ++ quicksort larger
where
smaller = filter (<= x) xs
larger = filter (> x) xs
Haskell's type system catches errors at compile time, turning your compiler into a powerful assistant that proves the correctness of your code before it ever runs.
processData = format . validate . parse
-- Right to left, like mathematics
Haskell is a purely functional programming language where every function is a mathematical function — no side effects, no mutable state, no hidden surprises. When you write f x = x + 1, you know with absolute certainty that f will always return the same result for the same input.
This isn't a limitation — it's a superpower. Purity enables equational reasoning: you can substitute equals for equals anywhere in your program, just like in algebra. Refactoring becomes fearless. Concurrency becomes trivial. And the compiler becomes your most trusted collaborator.
The type system isn't just checking your work — it's thinking with you. Types in Haskell are a language for expressing intent, and the compiler uses that language to verify that your program means what you think it means.
main :: IO ()
main = do
name <- getLine
let greeting = "Hello, " ++ name
putStrLn greeting
putStrLn "Welcome to Haskell."
fmap (+1) [1,2,3]
-- [2, 3, 4]
describe :: Int -> String
describe 0 = "nothing"
describe 1 = "unity"
describe _ = "something"
In Haskell, nothing is computed until it's needed. This isn't procrastination — it's precision. Lazy evaluation means you can define infinite data structures and only pay for what you use:
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
-- An infinite list of Fibonacci numbers
-- take 10 fibs => [0,1,1,2,3,5,8,13,21,34]
You just defined all Fibonacci numbers in a single line. The list extends forever, but Haskell only computes the elements you actually inspect. This is the programming equivalent of writing a book that only materializes the page you're reading.
class Describable a where
describe :: a -> String
instance Describable Bool where
describe True = "affirmative"
describe False = "negative"
type App a = ReaderT Config (ExceptT AppError IO) a
runApp :: Config -> App a -> IO (Either AppError a)
runApp cfg app = runExceptT (runReaderT app cfg)
fetchUser :: UserId -> App User
fetchUser uid = do
cfg <- ask
result <- liftIO $ queryDB (dbConn cfg) uid
case result of
Nothing -> throwError UserNotFound
Just user -> pure user
Haskell isn't just a programming language. It's a way of thinking — precisely, beautifully, and fearlessly. Every function you write is a proof. Every type is a contract. Every program is a composition of pure ideas.
Welcome to haskell.day