Your functional journey begins.
Every journey begins with understanding purity. A pure function always returns the same result for the same input -- no side effects, no surprises. In Haskell, purity isn't a guideline; it's enforced by the type system itself.
double :: Int -> Int
double x = x * 2
-- Always returns the same output
-- double 5 == 10, every time
Haskell's type system is your guide through the mountains. It catches errors at compile time and documents your intent, making impossible states unrepresentable. Types are your safety rope on this ascent.
data Maybe a = Nothing | Just a
safeDivide :: Int -> Int -> Maybe Int
safeDivide _ 0 = Nothing
safeDivide x y = Just (x `div` y)
Functions that take functions as arguments or return them as results. Map, filter, fold -- these are the tools that let you express complex transformations with elegant simplicity.
map :: (a -> b) -> [a] -> [b]
filter :: (a -> Bool) -> [a] -> [a]
-- Double all even numbers
doubleEvens = map (*2) . filter even
Typeclasses define shared behavior across types -- polymorphism without inheritance. Eq, Ord, Show, Functor: each one unlocks a new dimension of abstraction on your ascent.
class Functor f where
fmap :: (a -> b) -> f a -> f b
-- Lists, Maybe, IO -- all Functors
fmap (+1) [1,2,3] -- [2,3,4]
fmap (+1) (Just 5) -- Just 6
The summit challenge. Monads let you sequence computations while managing context -- IO, state, failure, and more -- all within a pure framework. Master this, and the peak is yours.
(>>=) :: Monad m => m a -> (a -> m b) -> m b
-- Chain computations elegantly
getLine >>= putStrLn
-- Read input, then print it
The quest through Haskell's landscape is complete. From pure functions to monads, you've ascended through the fundamentals of functional programming.