Extensible Effects in the van Laarhoven Free Monad
aaronlevin.ca
aaronlevin.ca
Seen in this light, the van Laarhoven Free Monad seems closer to how application contexts work that the typical "free monad" type used in functional programming.
Because it's polymorphic over the underlying monad ("forall m. Monad m => ops m -> m a") I believe it lets you express the idea of "pure component whose effects are carried out only through its own dependencies". For example, injecting java.time.Clock in your program logic instead of calling LocalTime.now().
Regarding effects, I found Koka to be a breath of fresh air: https://koka-lang.github.io/koka/doc/book.html#why
Haskell has lots of things that either can't be made Monads or are even deliberately not Monads (to preserve parallelism).
Another way of looking at this which is perhaps not so brain-twisting is that in most languages you start out with the ability to perform arbitrary side effects at any point in the program, which gives the programmer a lot of power but makes the program hard to reason about. In Haskell the "default state" is pure functions, which are great for reasoning about your program but much less powerful (no side effects). To this we can selectively add Functor, Applicable, and Monad instances to recover the ability to express side effects to varying degrees while still keeping most of the program pure. The fact that you have a choice about how much monadic code to introduce into your program is why monads are such a big topic in Haskell.
Not very sure if this is what you were asking about but yes, you can write functions that are polymorphic in their effect. E.g. the map function takes a function that has some effect e and the map function itself has the same effect e