Sono relativamente nuovo a Haskell e sto cercando di capire come azioni diverse possono essere eseguite in sequenza usando la notazione. In particolare, sto scrivendo un programma per confrontare un algoritmo (una funzione)
foo :: [String] -> [String]
A questo scopo vorrei 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 richiedere una conversione (ad esempio in millisecondi) ma questo non è l'argomento di questa domanda.
È questo il modo corretto per misurare il tempo necessario per calcolare la funzione foo su qualche argomento listaLista?
In altre parole, l'espressione foo inputList
sarà completamente ridotta prima che l'azione end <- getCPUTime
venga eseguita? Oppure r
sarà associato solo al thunk foo inputList
?
Più in generale, come posso garantire che un'espressione sia completamente valutata prima che venga eseguita un'azione?