Поскольку никто не пытался ответить в течение дня, я сделаю это. Я понимаю проблему, которую вы обсуждаете, но ответ, вероятно, должен зависеть от операционной системы, языка и библиотеки времени выполнения.
Общая идея заключается в том, что когда мышь выходит из строя, вы запускаете асинхронные вычисления. Это вычисление «блокирует» события и обрабатывает их в своем собственном цикле при получении, делая то, что вам нужно; это существует, когда кнопка мыши работает. Хотя это выглядит так, как будто оно работает как императивный поток, в действительности, когда вычисление «блокируется», оно просто возвращает контроль тому, откуда оно было запущено (основной поток GUI, вызывающий событие нажатия мыши, предположительно ). Таким образом, состояние инкапсулируется в то, что выглядит как лексически локальная область вычислений. Это волшебство должно быть обработано во время выполнения языка, так что это насколько мы можем получить с ответом, не зависящим от языка и ОС.
Что касается примера такой реализации, проверьте этот ответ и статью Томаса Петричека , в которой обсуждается ваш вопрос, но в узких настройках Windows, .NET и F #. Есть книга того же Perticek, «1011 * Функциональное программирование в реальном мире: с примерами на F # и C # », где те же самые идеи, как ни удивительно, выражены в C #, обычно не считаются функциональным языком. Глава 16, если мне не изменяет память, твоя.
Что касается инкапсуляции состояния в языковой программе IP / OO, вы можете создать экземпляр класса в вашем обработчике mouse_down. Экземпляр регистрируется в среде выполнения, чтобы получать другие события мыши и пользовательского интерфейса, обрабатывать их, выполнять всю работу и, когда необходимо (мышь поднимается или система управления окнами отменяет режим захвата), отменяет регистрацию и уничтожает себя. Не так элегантно, как это допускает функциональный язык, но все же намного лучше, чем сохранение изменяемого состояния в общем классе пользовательского интерфейса.