Sono relativamente nuovo per Haskell e sto cercando di capire come azioni diverse possono essere eseguite in sequenza usando la notazione. In particolare, sto scrivendo un programma per riferimento un algoritmo (una funzione)Come forzare la valutazione in Haskell?
foo :: [String] -> [String]
A questo proposito mi piacerebbe scrivere una funzione come
import System.CPUTime
benchmark :: [String] -> IO Integer
benchmark inputList = do
start <- getCPUTime
let r = foo inputList
end <- getCPUTime
return (end - start) -- Possible conversion needed.
L'ultima riga potrebbe aver bisogno di una conversione (ad esempio in millisecondi) ma questo non è l'argomento di questa domanda.
È questo il modo corretto di misurare il tempo necessario per calcolare la funzione foo su qualche argomento listaLista?
In altre parole, l'espressione foo inputList
verrà completamente ridotta prima che venga eseguita l'azione end <- getCPUTime
? O sarà r
legato solo al thunk foo inputList
?
Più in generale, come posso garantire che un'espressione sia completamente valutata prima che venga eseguita un'azione?
Questa domanda è stato chiesto un paio di mesi fa su programmatori (vedi here) ed aveva una risposta accettato lì, ma è stato chiuso come off-topic, perché appartiene in caso di overflow dello stack. Non è stato possibile spostare la domanda in stack overflow perché è precedente a 60 giorni. Quindi, d'accordo con i moderatori, sto ripubblicando la domanda qui e postando la domanda accettata perché penso che contenga alcune informazioni utili.
Se siete solo interessati a benchmarking, si potrebbe desiderare di controllare le [criterio] (http://hackage.haskell.org/package/criterion) biblioteca. – hugomg
La funzione 'foo' non verrà eseguita dal momento in cui si raggiunge la linea finale. Le funzioni di Haskell sono valutate solo su richiesta, quindi dovrai fare qualcosa con quel valore 'r' prima dell'assegnazione a' end'. –