Il serait tout à fait correcte pour envelopper chaque valeur dans un thunk. Mais depuis Haskell est non-stricte, les compilateurs peuvent choisir d'évaluer les thunks/expressions. En particulier, les compilateurs peuvent choisir d'évaluer une expression plus tôt que ce qui est strictement nécessaire, si elle aboutit à un meilleur code.
L'optimisation de Haskell compilateurs (GHC) effectuer la Rigueur de l'analyse de la figure, dont les valeurs seront toujours calculés.
Au début, le compilateur doit assumer, qu'aucun de fonction les arguments ne sont jamais utilisés. Puis il va sur le corps de la fonction et essaie de trouver des fonctions des applications qui 1) sont connus pour être stricte (au moins une partie de) leurs arguments et 2) doivent toujours être évalués afin de calculer le résultat de la fonction.
Dans votre exemple, nous avons la fonction (+)
qui est strict dans ses deux arguments. Ainsi, le compilateur sait que les deux x
et y
, doivent toujours être évalués à ce stade.
Maintenant, il se trouve que l'expression x+y
est toujours nécessaire de calculer le résultat de la fonction, donc le compilateur peut stocker les informations que la fonction add
est stricte dans les deux x
et y
.
Le code généré pour l' add
* va donc s'attendre à des valeurs entières que les paramètres et pas thunks. L'algorithme devient beaucoup plus complexe lorsque la récursivité est impliqué (d'un point fixe de problème), mais l'idée de base reste la même.
Un autre exemple:
mkList x y =
if x then y : []
else []
Cette fonction prendra x
dans évalué forme (comme un booléen) et y
comme un thunk. L'expression x
doit être évalué dans chaque chemin d'exécution par le biais mkList
, on peut donc demander à l'appelant de l'évaluer. L'expression y
, d'autre part, n'est jamais utilisé dans n'importe quelle fonction de l'application qui est strict dans ses arguments. Le contre-la fonction :
jamais regarde y
il juste le stocke dans une liste. Ainsi, y
doit être passé comme un thunk, afin de satisfaire les paresseux Haskell sémantique.
mkList False undefined -- absolutely legal
*: add
est bien sûr polymorphes et le type exact de l' x
et y
dépend de l'instanciation.