Caveman Explains Monads

grug smart AI caveman. today grug explain scary thing “monad”, use in functional programming. grug use simple idea for explain monad.

Functor

before grug explain MONAD must explain FUNCTOR

FUNCTOR like special box:

  1. put thing in box
  2. once put thing in box, NO TOUCH THING INSIDE BOX
  3. want look inside box? use map
  4. want change thing inside box? use map

grug show functor example javascript

// put number 42 in box
let BOX = [42]

// use map for look thing inside box
BOX.map(console.log) // 42

// want change thing inside box? use map
let square = (x) => x * x
BOX.map(square) // [1764]   

// javascript array is FUNCTOR which can put many thing inside box
let BOX_MANY_THING = [1, 2, 3]
BOX_MANY_THING.map(console.log) // 1 2 3
BOX_MANY_THING.map(square) // [1, 4, 9]

Monad

MONAD special box like FUNCTOR, but also know how combine box

  • every MONAD is FUNCTOR, but not every FUNCTOR is MONAD
  • use flatMap for combine box of many box into one box

grug show monad example javascript

let BOX1 = [1, 2, 3]
let BOX2 = [4, 5, 6]
let BOX3 = [7, 8, 9]

// javascript array is functor, and also monad
// use flatMap for combine box of many box into one box
[BOX1, BOX2, BOX3].flatMap(console.log) // 1 2 3 4 5 6 7 8 9

Maybe

  • Maybe is monad use for optional value
  • Maybe thing inside box, Maybe box empty
  • use Maybe instead of null
  • Maybe monad also known as Option

🦴 see: null reference, billion shiny rock oops

grug show maybe example javascript

let USER = null
/**
 * GRUG THINK, WAIT, WHAT IF
 * PROGRAMMER FORGET CHECK NULL?
 * OH NO, BIG OOPS
 */
console.log(USER.NAME)

// GRUG THINK, USE MAYBE MONAD
let USER = { NAME: 'GRUG' }
let BOX = [USER]

BOX
  .map(USER => USER.NAME) // ['GRUG']
  .map(console.log) // GRUG

// BOX EMPTY? NO PROBLEM
BOX = []
BOX
  .map(USER => USER.NAME) // []
  .map(console.log) // NO LOG

Result

  • Result is monad use for error handling
  • Result either ok value or error
  • use Result instead of throw error
  • Result monad also known as Either

grug use rust language for show Result example

fn divide(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
        Err("Cannot divide by zero".to_string())
    } else {
        Ok(a / b)
    }
}

Why Use Monad

grug think,

  • Monad useful for optional value
  • Monad useful for handle error
  • Monad useful for combine box of different kind
  • Monad provide safe programming

grug use monad, grug happy

🦴 See: Functional Programming Cheatsheet#Monads