Sappiamo tutti (o dovremmo sapere) che Haskell è pigro per impostazione predefinita. Niente viene valutato fino a quando non deve essere valutato. Quindi quando deve essere valutato qualcosa? Ci sono punti in cui Haskell deve essere severo. Io chiamo questi "punti di rigore", anche se questo termine particolare non è così diffuso come pensavo. Secondo me:
La riduzione (o valutazione) in Haskell si verifica solo nei punti di rigore.
Quindi la domanda è: quali sono, precisamente , i punti di rigore di Haskell? Il mio intuito dice che main
, seq
/ modelli bang, pattern matching, e qualsiasi IO
azione effettuata tramite main
sono i punti principali di severità, ma io non so davvero perché lo so.
(Inoltre, se non sono chiamati "punti di severità", cosa sono hanno chiamato?)
Immagino che una buona risposta includerà alcune discussioni su WHNF e così via. Immagino anche che possa toccare il lambda calcolo.
Modifica: pensieri aggiuntivi su questa domanda.
Mentre ho riflettuto su questa domanda, penso che sarebbe più chiaro aggiungere qualcosa alla definizione di un punto di rigore. I punti di rigore possono avere contesti e profondità (o rigidità) variabili . Ritornando alla mia definizione che "la riduzione di Haskell si verifica solo nei punti di rigore", aggiungiamo a questa definizione questa clausola: "un punto di rigore viene attivato solo quando il contesto circostante viene valutato o ridotto".
Quindi, fammi provare a iniziare con il tipo di risposta che voglio. main
è un punto di rigore. È appositamente designato come il principale punto di rigore del suo contesto: il programma. Quando il programma ( main
il contesto) viene valutato, viene attivato il punto di rigore principale. La profondità di Main è massima: deve essere valutata completamente. Main è solitamente composto da azioni IO, che sono anche punti di rigore, il cui contesto è main
.
Ora provi: discuti seq
e corrispondenza dei modelli in questi termini. Spiegare le sfumature dell'applicazione della funzione: in che modo è rigorosa? Come non lo è? Di cosa deepseq
? let
e case
dichiarazioni? unsafePerformIO
? Debug.Trace
? Definizioni di primo livello? Tipi di dati rigorosi? Schemi bang? Ecc. Quanti di questi elementi possono essere descritti in termini di corrispondenza di sequenze o pattern?
seq
e il pattern matching siano sufficienti, con il resto definito in termini di quelli. Penso che il pattern matching assicuri la severità delleIO
azioni, per esempio.