Nous savons tous (ou devrions savoir) que Haskell est paresseux par défaut. Rien n'est évalué tant qu'il n'a pas été évalué. Alors, quand faut-il évaluer quelque chose? Il y a des points où Haskell doit être strict. J'appelle ces «points de rigueur», bien que ce terme particulier ne soit pas aussi répandu que je l'avais pensé. Selon moi:
La réduction (ou évaluation) dans Haskell ne se produit qu'aux points de rigueur.
La question est donc: quels sont précisément les points de rigueur de Haskell? Mon intuition dit que main
, seq
/ modèles bang, pattern matching, ainsi que toute IO
action effectuée par main
les points de strictness primaires, mais je ne sais pas vraiment pourquoi je sais.
( De plus, si elles ne sont pas ce qui appelle des « points », de strictness sont ils appelés?)
J'imagine qu'une bonne réponse inclura une discussion sur WHNF et ainsi de suite. J'imagine aussi que cela pourrait toucher le calcul lambda.
Edit: réflexions supplémentaires sur cette question.
En réfléchissant à cette question, je pense qu'il serait plus clair d'ajouter quelque chose à la définition d'un point de rigueur. Les points de rigueur peuvent avoir des contextes et des profondeurs variables (ou rigueur). Revenant à ma définition selon laquelle «la réduction en Haskell ne se produit qu'aux points de rigueur», ajoutons à cette définition cette clause: «un point de rigueur n'est déclenché que lorsque son contexte environnant est évalué ou réduit».
Alors, laissez-moi essayer de vous lancer sur le genre de réponse que je veux. main
est un point de rigueur. Il est spécialement désigné comme le premier point de rigueur de son contexte: le programme. Lorsque le programme ( main
le contexte du programme) est évalué, le point de rigueur de main est activé. La profondeur de Main est maximale: elle doit être pleinement évaluée. Main est généralement composé d'actions IO, qui sont également des points de rigueur, dont le contexte est main
.
Maintenant, vous essayez: discuter seq
et faire correspondre les modèles en ces termes. Expliquez les nuances de l'application des fonctions: en quoi est-elle stricte? Comment n'est-ce pas? Et quoi deepseq
? let
et case
déclarations? unsafePerformIO
? Debug.Trace
? Définitions de premier niveau? Types de données stricts? Modèles de bang? Etc. Combien de ces éléments peuvent être décrits en termes de seq seulement ou de correspondance de motifs?
seq
la correspondance des motifs est suffisante, le reste étant défini en fonction de ces éléments. Je pense que la correspondance de motifs assure la rigueur desIO
actions, par exemple.