In Rust, the functions Result::and_then, Result::map, Option::and_then, Option::map, etc. are pretty much all saying the exact same thing, but they need to be reimplemented over and over again. With Haskell, Result and Option (and [], QuickCheck.Gen, Data.Binary.Get, etc.) just need to implement return and (>>=), and they get a ridiculous amount of useful functions for free (mapM_, foldM_, forever, ap, etc.). That's a "large chunk of code" saved in my opinion.
Having popular interfaces like monad, applicative functors, monoids etc also suggests common ways to structure any API you are working on.
If you design an API from scratch and have to implement everything again and again, you might be tempted into a pretty arbitrary breakdown of the problem space.
Whereas in Haskell personal laziness drives you to look hard to see if you can express your API in terms of foldable and traversable or monads etc so that you get lots of functions for free.
Those common interfaces also automatically suggest gaps in your API that otherwise you would have only noticed after using your API for a while (or by being a very experienced programmer).
In Rust, the functions Result::and_then, Result::map, Option::and_then, Option::map, etc. are pretty much all saying the exact same thing, but they need to be reimplemented over and over again. With Haskell, Result and Option (and [], QuickCheck.Gen, Data.Binary.Get, etc.) just need to implement return and (>>=), and they get a ridiculous amount of useful functions for free (mapM_, foldM_, forever, ap, etc.). That's a "large chunk of code" saved in my opinion.
https://hackage.haskell.org/package/base-4.14.0.0/docs/Contr...
And, of course, they also get some very nice sugar in the form of do notation.