C'est une déclaration de rigueur. Fondamentalement, cela signifie qu'il doit être évalué selon ce que l'on appelle la "forme normale de tête faible" lorsque la valeur de la structure de données est créée. Regardons un exemple, pour voir ce que cela signifie:
data Foo = Foo Int Int !Int !(Maybe Int)
f = Foo (2+2) (3+3) (4+4) (Just (5+5))
La fonction f
ci-dessus, une fois évaluée, renverra un "thunk": c'est-à-dire le code à exécuter pour déterminer sa valeur. À ce stade, un Foo n'existe même pas encore, juste le code.
Mais à un moment donné, quelqu'un peut essayer de regarder à l'intérieur, probablement à travers une correspondance de modèle:
case f of
Foo 0 _ _ _ -> "first arg is zero"
_ -> "first arge is something else"
Cela va exécuter suffisamment de code pour faire ce dont il a besoin, et pas plus. Il créera donc un Foo avec quatre paramètres (car vous ne pouvez pas regarder à l'intérieur sans qu'il existe). Le premier, puisque nous le testons, nous devons évaluer tout le chemin vers 4
, où nous réalisons qu'il ne correspond pas.
La seconde n'a pas besoin d'être évaluée, car nous ne la testons pas. Ainsi, plutôt que d' 6
être stockés dans cet emplacement mémoire, nous allons stocker le code d'évaluation possible plus tard, (3+3)
. Cela ne deviendra un 6 que si quelqu'un le regarde.
Le troisième paramètre, cependant, a un !
devant, il est donc strictement évalué: (4+4)
est exécuté et 8
est stocké dans cet emplacement de mémoire.
Le quatrième paramètre est également strictement évalué. Mais voici où cela devient un peu délicat: nous évaluons pas complètement, mais seulement pour une forme de tête normale faible. Cela signifie que nous déterminons si c'est Nothing
ou Just
quelque chose, et stockons cela, mais nous n'allons pas plus loin. Cela signifie que nous ne stockons pas, Just 10
mais en fait Just (5+5)
, laissant le thunk à l'intérieur sans évaluation. Il est important de le savoir, bien que je pense que toutes les implications de cela dépassent la portée de cette question.
Vous pouvez annoter des arguments de fonction de la même manière, si vous activez l' BangPatterns
extension de langage:
f x !y = x*y
f (1+1) (2+2)
retournera le thunk (1+1)*4
.