The infectious nature is just how things work with types. Imagine if you had to annotate a function with IO every time you do something that reaches for something else outside of the program. You would either design things differently so that IO usage is minimized or you would make everything infected by IO.
With Async, people are still figuring things out.
I've encountered a bunch of code bases that are polluted with async when a better design could have removed it completely.