Ci sono due cose da fare qui.
primo luogo, considerare
let x = sum [1..1000000] in 42
Haskell è pigro. Poiché in realtà non facciamo nulla con x
, non viene mai calcolato. (Il che è altrettanto buono, perché sarebbe leggermente lento.) In effetti, se lo compili, il compilatore vedrà che x
non viene mai usato e lo elimina (cioè non genera alcun codice compilato per esso).
Secondo, chiamare putStrLn
in realtà non stampa nulla. Piuttosto, restituisce IO()
, che può essere considerato come una sorta di "oggetto comando I/O". Il solo oggetto comando è diverso da che esegue. In base alla progettazione, l'unico modo per "eseguire" un oggetto comando I/O è restituirlo da main
. Almeno, è in un programma completo; GHCi ha la caratteristica utile che se si inserisce un'espressione che restituisce un oggetto comando I/O, GHCi lo eseguirà per voi.
L'espressione restituisce 42; di nuovo, f
non viene utilizzato, quindi non fa nulla.
Come sottolinea chi
, è un po 'come dichiarare una funzione locale (zero-argument) ma mai chiamarla. Non ti aspetteresti di vedere alcun risultato.
Si può anche fare qualcosa di simile
actions = [print 5, print 6, print 7, print 8]
Questo crea un elenco di oggetti di comando I/O. Ma, ancora una volta, non lo fa execute nessuno di loro.
In genere quando si scrive una funzione che esegue I/O, si tratta di un blocco di operazioni che raggruppa tutto in un unico oggetto comando I/O gigante e lo restituisce al chiamante. In tal caso, non è davvero necessario capire o fare qualcosa riguardo a questa distinzione tra che definisce un oggetto comando e in esecuzione su. Ma la distinzione è ancora lì.
È forse più facile vederlo con una monade che ha una funzione di esecuzione esplicita. Ad esempio, runST
prende un oggetto comando ST, lo esegue e restituisce la risposta. Ma (diciamo) newSTVar
, da solo, non fa altro che costruire un comando ST; devi runST
che prima di tutto effettivamente "accade".
Si potrebbe voler leggere su ['let' vs' <-'] (http://stackoverflow.com/q/28624408/3234959). Non è esattamente il problema che stai avendo ora, ma potrebbe essere d'aiuto. – chi
Leggere [Perché non riesco a forzare un'azione IO con seq?] (Http://stackoverflow.com/q/20324446/510937) per ulteriori informazioni sulla valutazione e l'esecuzione di azioni IO. – Bakuriu