Attualmente sto imparando Haskell (essendo un programmatore di mestiere, ma questo è il mio primo tentativo di linguaggio funzionale).Perché questo codice non è spazio costante?
Desidero scrivere una funzione che analizza una lista e restituisce sia l'elemento minimo che massimo di tale elenco. Una sorta di cosa fanno le funzioni Preludio minimum
e maximum
, ma entrambe allo stesso tempo. Mi è venuta in mente il seguente codice:
import Data.List
-- Declaration of rand
minMax :: [Int] -> Maybe (Int, Int)
minMax [] = Nothing
minMax (x:xs) = Just (foldl' f (x, x) xs)
where
f (a, b) c = (if c < a then c else a, if c > b then c else b)
rand
è una funzione che genera una lista infinita di numeri. Il fatto è che quando ho aggiungere il main
seguente funzione:
main = print $ minMax $ take 1000000 $ rand 7666532
compilare ed eseguire tutto questo con profiling, mi mostra che utilizza più di 200 MB di memoria, quindi non è sicuramente una funzione costante dello spazio (che Mi piacerebbe che fosse).
La domanda è perché e cosa dovrei cambiare per risolverlo. Come ho capito, lo foldl'
piega l'elenco da sinistra (allo stesso modo in cui viene generato) e non è pigro, quindi non vedo perché l'utilizzo della memoria sia così elevato. Sono abbastanza sicuro che sia la funzione minMax
che non è corretto, in quanto è sufficiente stampare il suddetto elenco, utilizzando
main = print $ take 1000000 $ rand 7666532
mi dà l'utilizzo di 1 MB, una cosa che ho capito e si aspettano.
Si prega di modificare la domanda e aggiungere il codice completo, tra cui il definitivo ione di 'rand'. Usare una rigida piega a sinistra non costringe la valutazione degli elementi della coppia, qui, perché l'accumulatore è già in forma normale debole, e le tuple sono pigre. – Jubobs
O pepe il tuo codice con 'seq', o definisci un tipo di dati coppia rigoroso:' dati Coppia un b = Coppia! A! B' e usalo al posto di semplice vecchio '(a, b)'. – Jubobs
Vorrei menzionare [la libreria 'foldl'] (https://hackage.haskell.org/package/foldl-1.1.1/docs/Control-Foldl.html) che riassume efficacemente le pieghe in questo modo, in Infatti uno degli esempi forniti è: 'L.fold ((,) <$> L.minimum <*> L.maximum) [1..10000000]' –