Monad
A monad in functional programming is a design pattern that allows for sequential composition of operations while handling side effects in a controlled way. Monads originate from mathematical category theory, where they are a specific type of algebraic structure.
Components of monads:
| Mathematics | Programming | 
|---|---|
| An endofunctor T | A type constructor | 
| A natural transformation η (unit) | A way to wrap values (return) | 
| A natural transformation μ (multiplication) | A way to compose operations (bind) | 
A monad consists of two fundamental operations:
return(orunit/pure): Function that wraps a value in the monadbind(often as>>=): Operation that chains monadic computations together
Common examples of monads include:
- Maybe/Option monad: Handles computations that might return no value
 - List monad: Represents non-deterministic computations with multiple results
 - IO monad: Encapsulate side-effects while maintaining functional purity
 - State monad: Allows passing state through a sequence of computations
 - Reader monad: Provides access to a shared environment/configuration
 - Writer monad: Collects additional output (like logs) during computation
 
Monads are a core concept in Haskell. Languages like Scala, F# (and JavaScript libraries) have adopted monadic patterns.
Code Example
-- Maybe monad example
-- Function that might fail
halve :: Int -> Maybe Int
halve n | even n    = Just (n `div` 2)
        | otherwise = Nothing
-- Using bind (>>=) for chained computations
divideBySteps :: Int -> Maybe Int
divideBySteps n = return n >>= halve >>= halve >>= halve
-- The same using do notation
divideByStepsWithDo :: Int -> Maybe Int
divideByStepsWithDo n = do
  a <- halve n      -- If halve n returns Nothing, entire computation returns Nothing
  b <- halve a      -- Only runs if previous step succeeded
  halve b           -- Only runs if previous steps succeeded
main :: IO ()
main = do
  print $ divideBySteps 80        -- Just 10
  print $ divideBySteps 81        -- Nothing (fails at first step)
  print $ divideByStepsWithDo 80  -- Just 10