Monad tutorials have achieved what many startups crave - hockey stick growth.
This isn't a monad tutorial.
It could be a monad tutorial, but I still don't understand monads. I don't think I ever will.
Monads were invented to fuck with us developers of lesser minds, the ones who don't want to bend over backwards to maintain functional purity and would perhaps rather ... you know ... get things done instead. Really, sometimes I just want things to work. I don't even care how.
You see, monads are just a wrapper around values. Their rhetoric is Hey, there's this value here, but there's a whole bunch of conditions involved. You don't really need to know about those, just play according to the rules.
And then you're like Okay ... but just give me the value? I understand all the conditions, but I don't care about them, I just want the value.
Well no, no you can't have the value just like that. That would be silly. You can unwrap the monad, play around with the value, fiddle with all the knobs and dials, but once you're done, you have to put it back into the monad where it's safe.
Monads are the ultimate Dad's shiny red corvette that he lets you drive around the parking lot, but you must always put it back in the garage and never drive anywhere with it.
I wish my dad had a corvette.
Really, they're just annoying. Annoying little shits.
Yesterday I was doing something simple:
- take some values from mongodb
- draw a graph
I spent the entire day in Monad Hell getting it done in Haskell. And that's after the dependency hell of installing Chart on my computer ... cabal isn't very good, but that's a whole different blogpost.
You see, when you take some values out of Mongo, the operation might have failed! You know it didn't, you know everything should just crash and burn and alarms should be going off if it did, so it's never going to. Not as far as this piece of code is concerned.
But Haskell doesn't know that. It might have failed. So everything you get out is wrapped in the Maybe monad. Except sometimes it isn't.
known'::[Document] -> (UTCTime, Double)known' docs = (cast' $ (valueAt "time") (docs!!0),cast' $ (valueAt "amount") (docs!!0))-- Couldn't match expected type `Double' with actual type `Maybe a0'-- In the expression: cast' $ (valueAt "amount") (docs !! 0)
Great. Ok so those are maybes, don't really care, moving on.
By the way, if the function really does fail it either dies with an index out of bounds error (not enough Documents) or with some sort of fields weren't there error, if you give it the wrong sort of Document. So it's not like it could actually fail in a way that it would still work and those Maybes would be warranted.
plot.hs:52:7:Couldn't match expected type `Double'with actual type `Maybe Double'In the first argument of `(+)', namely `money'In the first argument of `(-)', namely `money + p'In the expression: money + p -
At this point you're (or at least I was) getting frustrated and you suddenly can't remember where that short and sweet description of instance was even though it kept slapping you in the face the whole time you were trying to figure out how to take a value out of some monad or another and keep it the fuck out.
I don't know what instances are, not completely, but they look like a magic thing that can make type conversions automatic. And that's awesome so I need to look it up.
Anyway, you settle for a simple function
double'::Maybe Double -> Doubledouble' Nothing = 0.0double' (Just x) = x
Everything works! Yay!
At no point in execution does that default value actually happen. Because you've made sure externally that the operation Haskell is unsure of will never fail, but hey, you're happy, haskell is happy, the code is somewhat ugly.
But at least it works.
Now I just wish the graph wasn't a fluke of currency conversions.
- Why free monads matter
- Monads and Programming
- Monad tutorials timeline
- Python Monads - new approach
I write articles with real insight into the career and skills of a modern software engineer. "Raw and honest from the heart!" as one reader described them. Fueled by lessons learned over 20 years of building production code for side-projects, small businesses, and hyper growth startups. Both successful and not.
Subscribe below 👇
Join Swizec's Newsletter and get insightful emails 💌 on mindsets, tactics, and technical skills for your career. Real lessons from building production software. No bullshit.
"Man, love your simple writing! Yours is the only newsletter I open and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. 👌"
Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.
Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.
Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help 👉 swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.
Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers 👉 ServerlessHandbook.dev
Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization
Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog
By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️