One way of thinking about this question is to compare existing debouncers that use an effects manager vs. those which do not.
Two debouncers which use an effects manager are:
Two debouncers which do not use an effects manager are:
Now, both approaches need to keep some state, of course.
The advantage of an effects manager is that it can keep some state behind the scenes, so to speak, without requiring the user of the package to integrate the state into the `model`, `msg` and `update` scheme in the usual way.
However, I don't think there is anything an effects manager can accomplish (at least with respect to debouncing) that cannot also be done without an effects manager, at the cost of additional wiring and verbosity. That is, at the cost of making the state visible, and requiring you to integrate it into your `model`, `msg` and `update` scheme, you can achieve everything you'd want with respect to debouncing without using an effects module.
In fact, there are some advantages in not using an effects module. If you look at the debouncers that use an effects module, they employ a string ID in order to distinguish between one debouncer and another. (That is, the module is possibly tracking the state for multiple debouncers internally, so you need to provide a string ID to distinguish between one and another). But, of course, this isn't entirely satisfactory, since it forces you to maintain some scheme of globally-unique strings within your program. (Which is not necessarily that hard, really, but it is something which you'd normally want to avoid).
That problem doesn't arise if you have to explicitly integrate some state into your `model`, `msg` and `update` in the usual way, since then you just provide the relevant state when needed ... you can't accidentally refer to the wrong bit of state by providing a string ID that is also used elsewhere.
Of course, there may be a clever way to write an effects module that avoids this problem.