2014-04-13 13 views
7

Prima di tutto un disclaimer, potrei aver frainteso completamente il modo in cui threepenny-gui funziona a causa della mia non così avanzata conoscenza di Haskell, quindi prendi le mie asserzioni con un pizzico di sale. :-)Perché alcuni dei combinatori di FRP a tre pence-gui funzionano su una monade MonadIO invece di essere puri?

Mi sembra che alcuni combinatori non siano puri per es.

stepper :: MonadIO m => a -> Event a -> m (Behavior a) 

Is stepper necessariamente operano su un certo tipo di IO monade (e non è quindi pura), o che sto mi fraintendere qualcosa qui? Seconda domanda, se quei combinatori sono davvero impuri, perché è così? Per me questo rende il codice per la costruzione del grafo degli eventi molto meno bello della banana reattiva, dal momento che si deve usare una monade IO invece di essere semplicemente semplici funzioni. Il codice sembra solo diventare più complicato allora in banana reattiva.

Ancora più spaventoso, valueChange sembra essere puro dal tipo

valueChange :: Element -> Event String 

ma in realtà usando unsafeMapIO dentro, così è effettivamente facendo nascosta IO? Ancora una volta, potrei fraintendere qualcosa, ma non è questo il peccato più grave in Haskell? Era anche confuso, non potevo dire dal tipo come stava avvenendo la registrazione di richiamata ... questo non mi è mai successo prima in Haskell ... Questo è stato fatto per risparmiare agli utenti che hanno a che fare con la monade Frameworks?

risposta

5

Non sono un utente di threepenny-gui, ma posso darti un po 'di informazioni sulle tue domande dalla lettura del codice.

In primo luogo per stepper: Sembra che internamente threpenny-gui utilizzi IORef per tenere traccia dei parametri di accumulo. Ecco perché stepper richiede MonadIO. Tuttavia, non penso che ciò richieda IO a build il tuo grafico degli eventi, significa solo che deve eseguire in IO. Questo non dovrebbe causare alcun imbarazzo per te come utente API. Se pensi che sia, per favore pubblica una domanda più specifica.

In secondo luogo per quanto riguarda valueChange in fase di implementazione in termini di una funzione non sicura: Sì, questo è molto comune vedere nelle librerie Haskell. Gli autori delle librerie Haskell spesso usano funzioni non sicure quando sanno che il modo in cui vengono utilizzati è effettivamente sicuro per tutti i possibili percorsi di esecuzione, ma non è possibile dimostrarlo al sistema di tipi. In altre parole, gli autori di librerie usano le operazioni non sicure in modo sicuro in modo da non doverle!

+0

In pratica significa che se voglio fare qualcosa con il comportamento restituito da stepper devo prima "scartarlo" dalla monade IO, cioè usare >> =, fmap o notazione. Questo rende il codice molto più complicato di quanto avviene nel caso di banana reattiva in cui il grafico degli eventi non viene costruito utilizzando una Monad (la rete di eventi è costruita utilizzando la monade Frameworks, ma è per la registrazione di inserimenti, una cosa diversa). –

+0

La mia comprensione della monade IO è che esiste per garantire la trasparenza referenziale. Fintanto che tutto ciò che accade dentro la monade IO viene mantenuta la trasparenza referenziale di tutte le funzioni. La trasparenza referenziale è ancora mantenuta in pratica quando si usano funzioni come valueChange? –

+0

@ miguel.negrao: Sì, Heinrich avrà scritto questa funzione con molta attenzione, in modo da mantenere la trasparenza referenziale. –

2

Questa risposta è complementare a Tom Ellis'. Copre il modo in cui giustificherei i combinatori di FRP monadici dal punto di vista di un utente di Threepenny.

Con tre soldi, le probabilità sono che una grande parte del grafico evento sarà costruito da Element s, che vivono in UI (un involucro sottile per IO), perché sono legati a un DOM in un browser. Stando così le cose, ha senso rimuovere l'indirezione implicata nel collegare esternamente qualcosa come la banana reattiva (come faceva il vecchio pacchetto reactive-banana-threepenny). Nel caso di reactive-banana-threepenny, l'indirezione non era limitata all'utilizzo della monade Frameworks, ma implicava anche la conversione tra i diversi tipi di eventi di banana reattiva e di tre penny (vale anche la pena considerare che FRP in Threepenny è facoltativo ; puoi anche utilizzare gli eventi in modo tradizionale e imperativo).

Nel complesso, si tratta di un compromesso: per eliminare qualche riferimento indiretto e rendere l'API più immediatamente accessibile, viene sacrificata una certa pulizia nella definizione dei grafici degli eventi. Nella mia esperienza, tuttavia, il trade-off è valsa la pena.

Su una nota di chiusura, questo discussion I had with Heinrich nel momento in cui si passa da reattivo-banana-trepenny può far luce sulla questione.

Problemi correlati