No joke that’s pretty much every example I came across trying to get my head around it :D.
Not sure if using analogies is helpful or just going to be more confusing but, the way I think of a monad is similar to how I used to cook back when I worked in restaurants.
I’d prep all my ingredients in small containers so I wouldn’t forget anything, and they’d be ready to go when needed.
Then I’d start adding them to the main mixing bowl, one step at a time.
If I forgot an ingredient or accidentally flipped the bowl, the recipe would fail — you can’t keep baking after that.
So a monad is like that bowl: if you mess up, it just dumps everything out and resets your little prep bowls, instead of letting you keep going and make a batch of shitty cookies
The “main-bowl” is the monad (the context that holds your values).
The “prep bowls” are the individual values or functions ready to be chained.
The “dump/reset” is the idea that once something goes wrong, the chain stops safely.
And “shitty cookies” are the result of not putting a monad in place and just sending it.
Maybe someone with a more diverse programming background can explain it better.
But it’s basically a function checker usually wraped in IF ELSE and RETURN.
Some pseudo code in case my analogy doesn’t make sense.
def main():
bowl = get_flour()
bowl = add_butter(bowl)
if bowl is None:
return"Recipe failed — restart!"
bowl = add_sugar(bowl)
if bowl is None:
return"Recipe failed — restart!"return bake(bowl)
God, you guys are idiots, it’s so simple
No joke that’s pretty much every example I came across trying to get my head around it :D.
Not sure if using analogies is helpful or just going to be more confusing but, the way I think of a monad is similar to how I used to cook back when I worked in restaurants. I’d prep all my ingredients in small containers so I wouldn’t forget anything, and they’d be ready to go when needed. Then I’d start adding them to the main mixing bowl, one step at a time. If I forgot an ingredient or accidentally flipped the bowl, the recipe would fail — you can’t keep baking after that.
So a monad is like that bowl: if you mess up, it just dumps everything out and resets your little prep bowls, instead of letting you keep going and make a batch of shitty cookies
The “main-bowl” is the monad (the context that holds your values).
The “prep bowls” are the individual values or functions ready to be chained.
The “dump/reset” is the idea that once something goes wrong, the chain stops safely.
And “shitty cookies” are the result of not putting a monad in place and just sending it.
Maybe someone with a more diverse programming background can explain it better. But it’s basically a function checker usually wraped in IF ELSE and RETURN.
Some pseudo code in case my analogy doesn’t make sense.
def main(): bowl = get_flour() bowl = add_butter(bowl) if bowl is None: return "Recipe failed — restart!" bowl = add_sugar(bowl) if bowl is None: return "Recipe failed — restart!" return bake(bowl)
Isn’t your example just the builder pattern?
Yeah, that explanation is missing the critical point of generically applying external functions through
flat_map
/bind
I think this is a good explanation: https://fsharpforfunandprofit.com/rop/
A monad is a builder that lets you use previous partial results to make decisions while you build.
I like your explanation, that makes a lot of sense