As one example, the program might be written in model-view-controller style:
* Your "model" is a type `Model`.
* Your "view" is a function of type `Model -> Display`.
* Your "controller" is a function of type `(Model * Event) -> Model`.
So you don't need to perform IO to get the mouse click, since your program definition was already setup to handle incoming events. The runtime is responsible for feeding your controller events to get a new model, then running your view on the new model to create a display, then actually rendering that display.
To clarify: the idea is that both the view and controller are built into the interpreter. The interpreted program builds the model and is written in a a purely functional and effect-free language
It achieves the goal of making your code side-effect free. The explicit goal of these sorts of projects is to push the side-effects to the very edge of the stack.
* Your "model" is a type `Model`.
* Your "view" is a function of type `Model -> Display`.
* Your "controller" is a function of type `(Model * Event) -> Model`.
So you don't need to perform IO to get the mouse click, since your program definition was already setup to handle incoming events. The runtime is responsible for feeding your controller events to get a new model, then running your view on the new model to create a display, then actually rendering that display.