How would a pure functional programming language with encapsulated effects via monads (e.g. haskell) deal with interrupts?
Usually, interrupt handlers modify some global state, but accessing a global monad does nothing to the actual state, so you would need to somehow pass in the mutable data structures from within the monad, and to sequence effects properly, the interrupt's monad has to be inserted into the monad that was interrupted from. I imagine you could make it so that interrupts are only enabled inside limited scopes, and then you can pass mutable assignables to the interrupt handler, and the monad resulting from the interrupt handler is sequenced into the monad that was interrupted. But this is very weird and not satisfying.
Another option is having the interrupts be sent via a channel. However I think this is not desirable because the interrupt might not be immediately handled, unless the program is blocking on the channel. You could spawn another thread and block on the channel, but you will have to have a main thread doing work, and you won't be able to immediately interrupt the work that the main thread is doing by sending a message.
Interrupts seem to be very different to other effects in that something is being done to you, rather than you doing something to someone else. Perhaps comonads are needed to encapsulate interrupts since it might be a co-effect? I don't know because I am not very familiar with comonads.