Most code that is written has effects - null returns, error returns, exceptions, IO, etc., etc. We can write a custom function to compose every pair of functions we write, but some clever people figured out there were patterns to this madness - map, flatMap, lift, return, etc. - and it's far more efficient to write those patterns once and reuse them.
Essentially, it's DRY at a higher level of abstraction.
You still have to write each composition operator separately; writing the code to compose null returns doesn't give you the code to compose IO. Only difference is whether they have separate names.
Essentially, it's DRY at a higher level of abstraction.