haskell .monster

a subaqueous meditation on pure abstraction

I

Shallows

0–40m
concept 01

A type is a promise
kept by the compiler.

We begin at the surface where light still reaches — where a program is merely a specification, and the sea is calm enough to see through to the sand. Here, lambdas are still small: they flicker in the shallows like silver fry.

greet :: String -> String
greet name = "hello, " ++ name
aside 02

"pure functions are fish that never rot —
they return the same scale in the same light, forever."

polyp 03

Referential Transparency

An expression may be replaced by its value. Nothing in the tide pool remembers being disturbed.

definition 04
data Maybe a
  = Nothing
  | Just a

The simplest sea creature: a box that may be empty. It teaches us to ask before we assume.

marginalia 05

Haeckel drew 4,000 species
of radiolarians by hand.
Not one of them IO.

invocation 06

Hover in clear water.

Before the descent, pause. The eye adjusts. The ear adjusts. The breath adjusts. Reading a type signature, like watching a kelp frond, is an act of patience: only after long observation does the whole shape become intelligible.

fmap :: Functor f => (a -> b) -> f a -> f b
II

Thermocline

40–200m
transition 07

The water
changes
temperature.

A layer of sudden cold, where the easy surface metaphors stop working and the sea reveals it has been composing itself all along. Here, the first monad arrives — not as an abstraction but as a rhythm of dependent steps.

(>>=) :: m a -> (a -> m b) -> m b
signature 08
class Functor f where
  fmap :: (a -> b)
       -> f a
       -> f b

class Functor f
  => Applicative f where
  pure  :: a -> f a
  (<*>) :: f (a -> b)
        -> f a
        -> f b
reflection 09

an applicative is a functor
that has learned to hold
its own breath.

We lift pure values into the current. We zip two floating things and make them speak.

creature 10

IO ()

A shape that performs. The only vertebrate in the phylum.

kelp 11

Monadic chains,
like kelp forests,
sway in sequence.

do
  name  <- readLine
  depth <- sense
  pure (descend name depth)

Each line is a frond. The frond above cannot see the frond below — it only yields, and trusts.

aside 12

the compiler is a very
patient marine biologist.

law 13

Functor Laws

fmap id      = id
fmap (f . g) = fmap f . fmap g

Identity. Composition. Two laws, no more, no less — a coral the right size.

III

Mesopelagic

200–1000m
category 14

A monad is a monoid
in the category
of endofunctors.

This sentence is a joke and a theorem simultaneously. The deeper you go, the less it matters which.

transformer 15
newtype StateT s m a
  = StateT
  { runStateT ::
      s -> m (a, s) }

instance Monad m
  => Monad (StateT s m)
  where
    return a = StateT $
      \s -> return (a, s)

A transformer stack is a column of organisms, each one breathing what the one below it exhales.

creature 16

Cont r a

The continuation monad swims sideways through time. It eats its own call-stack.

observation 17

Bioluminescence.

The deep produces its own light. A type signature at this depth does not describe behavior — it is the behavior, glowing faintly from within the compiler's darkness. Each inference is a flash.

foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
aside 18

at this pressure,
imperative idioms
simply crumple.

comonad 19

The Comonad

class Functor w => Comonad w where
  extract   :: w a -> a
  duplicate :: w a -> w (w a)

Where a monad produces context, a comonad is suspended inside it — a creature that experiences, rather than performs. The mirror-image of a jellyfish.

IV

Abyssal

> 4000m

Leviathan :: forall a. Monad m => Depth -> Silence -> m (Maybe Revelation)

koan 20

The monster is never shown. Only the shape it leaves in the type system. Only the pressure it exerts on the surrounding types.

terminus

surface again —
or do not.
the sea is patient.