(Sorry if this issue is stupid. I am not familiar with Haskell's threading model.)
The cats-effect introduction page says:
"As Haskell’s runtime uses green threading, a synchronous IO (and the requisite thread blocking) makes a lot of sense."
Whereas Wikipedia on Green Threads says:
"When a green thread executes a blocking system call, not only is that thread blocked, but all of the threads within the process are blocked.[5] To avoid that problem, green threads must use asynchronous I/O operations, ..."
These statements seem to contradict each other. I guess that Haskell has some kind of built-in logic for IO (like yielding the control to another green thread). Maybe the situation/reasoning could be explained some more.