Обработка событий в Haskell
Я хотел бы реализовать следующий сценарий в Haskell. у меня есть
перечислимый набор "событий", определенных следующим образом:
data MyEvent = Event1
| Event2
| Event3
Я хочу определить обработчики для этих событий, которые будут использоваться следующим образом:
eventLoop :: Handler h => h -> IO ()
eventLoop currentHandler = do
event <- getNextEvent
nextHandler <- currentHandler event
eventLoop nextHandler
В основном я хочу, чтобы обработчики могли возвращать себя или другого обработчика
обрабатывать будущие события. Это тип обработчиков, о которых я не уверен.
Моя первая идея заключалась в том, чтобы определить обработчики как простые функции, но их тип
бесконечно долго:
myHandler :: Event -> IO (Event -> IO (Event -> ... ))
Я подозреваю, что это можно решить с помощью класса типа, где каждый обработчик будет нужен
для реализации функции обработки событий (которая, в свою очередь, возвращает другой тип
тот же класс), но рекурсивное определение все равно будет применяться. Может кто-нибудь
более хорошо разбирающиеся в системе типа, указывают мне в правильном направлении? Я также
приветствуем любые другие действия.
Спасибо!
Ответы
Ответ 1
Ну, "бесконечные" типы обычно представляют собой развернутые рекурсивные типы. Итак, одна вещь, которую вы можете сделать, - сделать рекурсию явной, используя newtype
:
newtype Handler = Handler { runHandler :: Event -> IO Handler }
Это также, возможно, самое простое решение, поскольку оно позволяет избежать жонглирования классов типов и разных экземпляров, чтобы получить разные формы поведения - каждый обработчик может выбрать то, что он возвращает, поскольку они имеют единый интерфейс.
Заметим, что во многих случаях определение класса типа для решения этой проблемы совершенно излишне. Если вы имеете дело с полиморфным типом Handler h => h
, все, что вы можете сделать с этим типом, это использовать функции класса типа на нем. Если функции, определенные в этом типе, просты, вы можете сэкономить много хлопот, концептуально "предварительно применив" их.