DEV Community

Cover image for Pure Functions, Functors, Applicatives & Monads
conjurer
conjurer

Posted on

Pure Functions, Functors, Applicatives & Monads

Think of any wrapped context in Haskell (like Maybe) as a sealed plastic Lego storage box:

  • Data (like the number 5) is a red Lego block inside.
  • A Pure Function is an instruction sheet ("Attach a blue block").

Pure Function

No Lego boxes here—just instructions applied to raw blocks sitting on desk.
It only looks at the inputs explicitly passed. No database calls, no reading system clocks, no side effects. The same input always yields the exact same output.
pure function

addOne :: Int -> Int
addOne x = x + 1
Enter fullscreen mode Exit fullscreen mode

Functor (fmap / <$>)

Got some building instructions, but the Lego block is locked inside a sealed plastic box.
A Functor acts like a pair of reach-in gloves: it applies the instructions to the wrapped block without breaking the box.
functor

fmap (+1) (Just 5)  -- Returns Just 6
Enter fullscreen mode Exit fullscreen mode

Applicative (<*>)

What if both instructions AND Lego blocks are sealed in separate plastic boxes?
An Applicative opens both boxes, applies the boxed instructions to the boxed blocks, and seals the result inside a new third box.
applicative

(+) <$> Just 3 <*> Just 4  -- Returns Just 7
Enter fullscreen mode Exit fullscreen mode

Monad (>>=)

For building a sequential pipeline where Step 2 depends on what comes out of Step 1; and if any box is empty (Nothing), process should abort immediately (aka handle errors/exceptions alongside)-
a Monad acts as the assembly manager: it opens Box 1, checks the contents, picks the next instruction dynamically, and handles missing pieces without crashing the app.

calculate :: Double -> Maybe Double
calculate input = do
  step1 <- safeSqrt input       -- Step 1
  step2 <- safeSqrt (step1 + 5) -- Step 2 (depends on step1)
  pure step2
Enter fullscreen mode Exit fullscreen mode

TL;DR

tldr

Top comments (0)