È possibile implementare una forma limitata di FRP utilizzando processori di flusso. Ad esempio, utilizzando la libreria pipes
, si potrebbe definire una fonte di eventi:
mouseCoordinates :: (Proxy p) =>() -> Producer p MouseCoord IO r
... e si potrebbe allo stesso modo definire un gestore grafico che prende coordinate del mouse e aggiorna un cursore su una tela:
coordHandler :: (Proxy p) =>() -> Consumer p MouseCoord IO r
Poi si sarebbe collegare gli eventi del mouse al gestore tramite composizione:
>>> runProxy $ mouseCoordinates >-> coordHandler
e sarebbe eseguire solo il modo che ci si aspetta.
Come hai detto, questo funziona bene per una singola catena di fasi, ma per quanto riguarda le topologie più arbitrarie? Bene, dal momento che il tipo centrale Proxy
di pipes
è un trasformatore monad, è possibile modellare qualsiasi topologia arbitraria semplicemente annidando i trasformatori di monad proxy su se stessi. Ad esempio, ecco come si zip due flussi di ingresso:
zipD
:: (Monad m, Proxy p1, Proxy p2, Proxy p3)
=>() -> Consumer p1 a (Consumer p2 b (Producer p3 (a, b) m)) r
zipD() = runIdentityP $ hoist (runIdentityP . hoist runIdentityP) $ forever $ do
a <- request() -- Request from the outer Consumer
b <- lift $ request() -- Request from the inner consumer
lift $ lift $ respond (a, b) -- Respond to the Producer
Questo comporta come una funzione di curry. Lo si applica parzialmente a ciascun input in modo sequenziale e quindi è possibile eseguirlo quando viene applicato completamente.
-- 1st application
p1 = runProxyK $ zipD <-< fromListS [1..]
-- 2nd application
p2 = runProxyK $ p2 <-< fromListS [4..6]
-- 3rd application
p3 = runProxy $ printD <-< p3
Funziona proprio come ci si aspetta:
>>> p3
(1, 4)
(2, 5)
(3, 6)
Questo trucco generalizza a qualsiasi topologia.Puoi trovare molti più dettagli a riguardo in Control.Proxy.Tutorial nella sezione "Filiali, cerniere e fusioni". In particolare, dovresti dare un'occhiata al combinatore fork
che usa come esempio, che ti permette di dividere un flusso in due uscite.
Ah, stavo per pubblicare qualcosa di simile, ma rimanderò all'esperienza di qualcuno che in realtà ha scritto una libreria AFRP. :] –
Sembra che usando (A) FRP non sarei limitato a una struttura di grafi aciclici, è vero? – fho
Dalla mia risposta non mi è chiaro cosa succederebbe se alcuni aspetti dell'AFRP non fossero implementabili in termini o nel flusso recente in possesso di librerie conduit/pipe? – Davorak