>>= <$> :: -> <|> >>= :: -> <$> <|>

haskell.quest

Descend into the type-safe undergrowth.

λλλ

The Undergrowth

Types

In Haskell, every expression has a type. Types are the bedrock — the stone tablets upon which all safe computation is inscribed. They are checked at compile time, ensuring your programs are well-formed before they ever run.

data Tree a = Leaf
            | Branch (Tree a) a (Tree a)

height :: Tree a -> Int
height Leaf = 0
height (Branch l _ r) =
  1 + max (height l) (height r)

Functions

Functions are the vines that connect everything. In Haskell, they are first-class citizens — passed as arguments, returned as results, composed into elegant pipelines that transform data without mutation.

compose :: (b -> c) -> (a -> b) -> a -> c
compose f g x = f (g x)

-- The dot operator
(.) :: (b -> c) -> (a -> b) -> a -> c
(f . g) x = f (g x)

Purity

Pure functions are the moss-covered foundation. Given the same input, they always return the same output — no hidden state, no side effects, no surprises lurking in the undergrowth.

-- Pure: same input, same output
fibonacci :: Int -> Int
fibonacci 0 = 0
fibonacci 1 = 1
fibonacci n = fibonacci (n-1)
           + fibonacci (n-2)

The Stone Library

λλ

Monads

A monad is a design pattern for chaining computations. Think of it as a stone corridor with doors — each door opens only when the previous room yields a result. The Maybe monad handles absence. The IO monad tames the outside world.

class Monad m where
  return :: a -> m a
  (>>=)  :: m a -> (a -> m b) -> m b

safeDivide :: Int -> Int -> Maybe Int
safeDivide _ 0 = Nothing
safeDivide x y = Just (x `div` y)

computation :: Maybe Int
computation = do
  a <- safeDivide 100 5
  b <- safeDivide a 2
  return (a + b)

Functors

A functor is a mappable structure — a container you can reach into and transform the contents of, without disturbing the container itself. Lists, trees, optional values — all are functors.

class Functor f where
  fmap :: (a -> b) -> f a -> f b

instance Functor Maybe where
  fmap _ Nothing  = Nothing
  fmap f (Just x) = Just (f x)

doubled :: [Int]
doubled = fmap (*2) [1, 2, 3, 4]
-- [2, 4, 6, 8]

The Chamber of Types

Maybe a = Nothing | Just a
Either a b = Left a | Right b
[a] = [] | a : [a]
IO a — the world transformer
State s a = s -> (a, s)
Reader r a = r -> a

“Types are not constraints. They are the map that reveals the territory.”

Quest

λ

The quest continues. Every type checked, every function composed, every monad bound — another step deeper into the undergrowth of understanding.

λ >>= ∞