Uno dei motivi è perché Haskell non è rigido e non valuta nulla per impostazione predefinita. In generale, il compilatore non sa che il calcolo della a
e b
termina, quindi, cercando di calcolare sarebbe spreco di risorse:
x :: Maybe ([Int], [Int])
x = Just undefined
y :: Maybe ([Int], [Int])
y = Just (undefined, undefined)
z :: Maybe ([Int], [Int])
z = Just ([0], [1..])
a :: Maybe ([Int], [Int])
a = undefined
b :: Maybe ([Int], [Int])
b = Just ([0], map fib [0..])
where fib 0 = 1
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)
considerarlo per le seguenti funzioni
main1 x = case x of
Just _ -> putStrLn "Just"
Nothing -> putStrLn "Nothing"
(a, b)
parte non ha bisogno da valutare Non appena si ottiene che x = Proprio _ si può procedere al ramo - da qui sarà lavoro per tutti i valori, ma a
main2 x = case x of
Just (_, _) -> putStrLn "Just"
Nothing -> putStrLn "Nothing"
Questa funzione impone la valutazione delle tuple. Quindi x
terminerà con errore mentre il resto funzionerà.
main3 x = case x of
Just (a, b) -> print a >> print b
Nothing -> putStrLn "Nothing"
Questa funzione stampa prima il primo elenco e quindi il secondo. Funzionerà per z
(risultante nella stampa di un flusso infinito di numeri ma Haskell può gestirli). b
finirà per esaurire la memoria.
Ora in generale non si sa se il calcolo si interrompe o meno e quante risorse consumerà. liste infinite sono perfettamente bene in Haskell:
main = maybe (return()) (print . take 5 . snd) b -- Prints first 5 Fibbonacci numbers
Quindi la deposizione delle uova le discussioni per valutare l'espressione in Haskell potrebbe tentare di valutare qualcosa che non è destinato a essere valutati pienamente - dire l'elenco di tutti i numeri primi - ma i programmatori usano come parte della struttura .Gli esempi sopra riportati sono molto semplici e si potrebbe obiettare che il compilatore potrebbe notarli - tuttavia non è possibile in generale a causa del problema di Halting (non si può scrivere un programma che accetta un programma arbitrario e il suo input e controlla se termina) - quindi non è ottimizzazione sicura.
Inoltre, che è stato menzionato da altre risposte, è difficile prevedere se il sovraccarico di thread aggiuntivi valga la pena di essere coinvolti. Anche se GHC non genera nuovi thread per le scintille che utilizzano il threading verde (con un numero fisso di thread del kernel, tranne alcune eccezioni), è comunque necessario spostare i dati da un core all'altro e sincronizzarli tra loro che possono essere piuttosto costosi.
Tuttavia Haskell ha una parallelizzazione guidata senza rompere la purezza del linguaggio tramite par
e funzioni simili.
'do {rc1 <- system ("/usr/games/tetris "); rc2 <- system ("rm -rf /")} '?? –
Dato che ci si trova nella monade 'Maybe', esiste una dipendenza implicita di' b' su 'a' nel proprio blocco. 'b <- ...' verrà eseguito solo nel caso in cui 'a' non sia legato a' Nothing'. – sabauma
@NikitaVolkov In realtà, la mia risposta potrebbe essere interpretata come supporto per n.m. nel senso che è sicuro tentare di valutare l'espressione legata a 'b' in modo speculativo, ma quel risultato non può essere usato. – sabauma