Programação orientada a eventos em Haskell

5

Sou novo em Haskell, então essa é mais uma questão conceitual de alto nível. Eu li isto: link e tem isto:

run :: Domain -> [Event] -> IO ()

run dm [] = do
  events <- uiUpdate dm
  run dm events

run _ (EventExit:_) =
  return ()

run dm (e:es) =
  run (dmUpdate dm e) es

Portanto, o uiUpdate "geraria" eventos neste caso.

Estou tentando entender como isso funciona em um aplicativo em que você precisa enviar eventos. Um exemplo - digamos que você tenha uma GUI na qual você tenha um único contador int e três tipos de fontes de eventos:

  • Sistema de arquivos
  • Rede
  • Interação humana

Por simplicidade, o contador precisa ser aumentado ou diminuído sempre que algum tipo de evento acontecer (por exemplo, novo arquivo adicionado ou excluído, chamada HTTP com sucesso ou falha, humano digitado em um teclado ou clicado com um mouse).

Como você empurra esses eventos para o loop de eventos? Mais importante, eu não estou pedindo "aqui está como você pode fazer isso", mas "aqui está como os aplicativos Haskell do mundo real funcionam". Especialmente se houver opções diferentes usadas na prática.

    
por levant pied 21.04.2016 / 17:46
fonte

2 respostas

0

Em um aplicativo do mundo real, você fica à mercê de qualquer sistema de eventos que esteja usando. Normalmente, a biblioteca da GUI fornece o loop de eventos. Então, basta chamar a API para gerar o evento e não há diferença para nenhuma chamada de API.

Por exemplo, neste tutorial Gtk, você pode enviar um evento no retorno de chamada do botão. link Ou você pode adicionar um retorno de chamada usando a API Gtk que captura todos os eventos.

Se você está construindo seu próprio sistema a partir do zero com vários threads, basta projetar o loop de eventos para incluir funções para adicionar eventos. Será o mesmo que qualquer outra linguagem ou paradigma; você usa um mutex e bloqueia algo, depois envia o evento para onde quer que seus eventos vão. Você não pode realmente preencher a foto sem saber muito mais; você tem que entrar nas ervas daninhas e realmente estar implementando algo, porque não há uma única maneira de fazê-lo, e um loop de eventos é mais uma idéia do que uma coisa. É apenas uma função que analisa seus argumentos e chama outras funções usando callbacks.

O exemplo Gtk é provavelmente o mais "real", porque no mundo real você está usando uma biblioteca GUI imperativa que mantém (pelo menos uma cópia) a maior parte do estado do seu aplicativo.

    
por 02.01.2019 / 21:52
fonte
0
Vamos supor que você tenha implementações de cada uma de suas três origens, updateUi , updateFS e updateNet , e suponha que sejam todas do tipo () -> IO [Event] . Para reuni-los todos em uma lista, você pode apenas concat o resultado de cada

updateAll :: () -> IO [Event]
updateAll = do
  uis <- updateUi
  fss <- updateFs
  nets <- updateNet
  concat [uis, fss, nets]
    
por 02.01.2019 / 22:34
fonte