because it is declared as an effect - and implements a handle.
Think of it more like an interface. It turns out that many common patterns - async, IO, yielding can all be expressed with a handle - and the effect can be represented in the signature.
This allows the code to have which effect its ran in, at runtime - other commenters pointed out its very similar to dependency injection.
Ok so we are basically defining a named function signature that represents a side effect shape.
Then the implementation of these side effect is done elsewhere and assigned as the capability of a function, which is now deemed as impure by the compiler.
Think of it more like an interface. It turns out that many common patterns - async, IO, yielding can all be expressed with a handle - and the effect can be represented in the signature.
This allows the code to have which effect its ran in, at runtime - other commenters pointed out its very similar to dependency injection.