2012-06-04 26 views
7

Probabilmente non sto capendo molto bene la monade IO.Haskell IO Monad e memoria utilizzano

Se scrivo un'applicazione che dovrebbe funzionare per molti mesi, nel frattempo registrando il suo stato di avanzamento, la monade IO terrà tutte le informazioni del registro nella RAM fino alla fine?

Dal blog su IO Inside, modelli Haskell il mondo come

main :: RealWorld -> ((), RealWorld) 

in modo che IO non si verifica durante l'esecuzione della parte Haskell del codice, ma solo quando l'applicazione ritorna da main.

Probabilmente sto interpretando erroneamente questo. Qualcuno potrebbe spiegare quando Haskell fa effettivamente IO?

risposta

8

il moni IO manterrà tutte le informazioni di registro nella RAM fino alla fine?

No. Non si dovrebbe pensare a "IO monade" come a qualcosa che esegue azioni. È solo un modo matematico di rappresentare programmi imperativi. I programmi imperativi primitivi sono cose come getChar; >>= viene utilizzato per incollare due programmi insieme in un programma imperativo più ampio. La monade IO è l'insieme di tutti i programmi imperativi.

consideri un programma come

main = putStr "Hello, " >> putStrLn "world!" 

Ciò significa: main è un programma che esegue il programma putStr "Hello, ", e quando questo è fatto, esegue il programma putStrLn "world!". Non è necessario che l'interprete Haskell o il programma compilato mantenga nessuno stato in memoria tranne un puntatore di istruzioni, ad esempio "dove siamo e cosa eseguiamo successivamente".

La metafora RealWorld -> ((), RealWorld) potrebbe averti confuso poiché sembra implicare una trasformazione dello stato del mondo esterno in un nuovo stato che deve essere calcolato nella sua interezza, dopo di che il mondo può essere aggiornato per riflettere lo stato calcolato. Questo non è affatto ciò che accade. Il wiki Haskell avvisa a riguardo:

La seguente storia su IO non è corretta in quanto non può in realtà spiegare alcuni aspetti importanti dell'IO (inclusi l'interazione e la concorrenza).

+0

Grazie per la bella spiegazione. Ho letto "Learn You a Haskell" (attualmente nella mia seconda lettura della sezione monadi) e ho iniziato "Real-World Haskell". A meno che non mi sia sfuggito qualcosa, non è chiaro che IO si verifica immediatamente, ma piuttosto, come altre monadi, viene "accumulato" fino alla fine.Credo di aver bisogno di guardare l'output in linguaggio assembly del compilatore per convincermi :-). – Ralph

+0

La metafora 'RealWorld -> ((), RealWorld) sembra implicare che la trasformazione avvenga in forma pura e alla fine venga emessa solo nella sua interezza. Immagino che le implementazioni sottostanti delle operazioni di I/O avvengano effettivamente "su richiesta". – Ralph

+5

@ Ralph: la chiave per comprendere la monade IO è che accumula * programmi *, non effettivi input e output. Pochi tutorial di Haskell lo spiegano bene. –

4

il moni IO manterrà tutte le informazioni di registro nella RAM fino alla fine?

No. Supponendo che si stia utilizzando una strategia di registrazione ragionevole.

Haskell esegue l'I/O quando il risultato è richiesto dal programma; che per la maggior parte delle azioni è immediatamente. (L'eccezione sono le librerie di file di input pigri, in cui i file non vengono necessariamente letti finché i dati non vengono utilizzati dal programma).