Perché Haskell non è in grado di ottimizzare gli elenchi infiniti?

2

Diciamo che hai una lista %codice% e vuoi ottenere il l = [0, 2..] th numero quando n è piuttosto grande, ad esempio n . Quindi chiami n=123456789 . Sulla mia macchina, questo risulta in l !! 123456789 .

Quindi, perché Haskell non è in grado di realizzare che il numero all'indice out of memory è n e effettua una chiamata come 2n banale? O un esempio più estremo, l !! 1230981237 . Haskell non dovrebbe essere in grado di capire che ogni numero in [1..] !! 123456789 è [1,1..] ?

    
posta MartinHaTh 24.05.2014 - 02:30
fonte

2 risposte

8

Un compilatore sufficientemente intelligente potrebbe accorgersi di ciò in quei casi. Ma per i casi non banali, la ricerca di una forma chiusa spazia da un problema difficile a uno indecidibile. Un compilatore è un compilatore, non un matematico. Non esiste una procedura generale per trasformare l'ennesimo elemento di una sequenza in una forma semplice che non calcoli gli elementi precedenti, quindi nel migliore dei casi le ottimizzazioni sarebbero un mucchio di casi speciali (ad esempio per enumFromThen , che è cosa [0, 2, ..] desugars a). Ma non c'è nessuna motivazione per farlo: è banale da fare a mano, raro nel codice reale, e non è il tipo di schema che emerge come risultato di altre ottimizzazioni. Se vuoi l'ennesimo numero veloce, scrivi 2 * n . evens !! n potrebbe essere carino ma non vale la regola di riscrittura per rendere veloce.

    
risposta data 24.05.2014 - 02:41
fonte
2

Parte del lavoro di programmazione è riconoscere quando hai aggiunto una complicazione che non ha bisogno di esistere e rimuoverla.

In questo caso, ciò che stai facendo è trovare la voce 123456789th in un elenco in cui l'ennesima voce è 2 * n. Costruire la lista in primo luogo è un lavoro extra, che dovremmo rifiutare di fare.

Non sarebbe difficile per gli scrittori di compilatori di Haskell aggiungere un'ottimizzazione in grado di rilevare un potenziale miglioramento, ma se fosse aggiunto, si sarebbe mai usato sul codice non scritto specificamente per indicarlo? Ne dubito. I casi che fai notare sarebbero ovvi per il programmatore - così ovvio che non sarebbero mai stati scritti in primo luogo.

I compilatori sono programmi per computer, non "realizzano" nulla. Realizzare è qualcosa che gli umani fanno.

(Nitpick: non tutti gli elementi in [1..] sono 1)

    
risposta data 24.05.2014 - 04:20
fonte

Leggi altre domande sui tag