C'est une déclaration de rigueur. Fondamentalement, cela signifie qu'il doit être évalué à ce qu'on appelle une «forme de tête normale faible» lorsque la valeur de la structure de données est créée. Regardons un exemple, afin que nous puissions voir exactement 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 lors de son évaluation, retournera un « thunk »: à savoir, le code à exécuter pour déterminer sa valeur . À ce stade, un Foo n'existe même pas encore, juste le code.
Mais à un certain moment, quelqu'un peut essayer de regarder à l'intérieur, probablement par une correspondance de motif:
case f of
Foo 0 _ _ _ -> "first arg is zero"
_ -> "first arge is something else"
Cela va exécuter du code assez pour faire ce dont il a besoin, et pas plus. Donc, il va créer un Foo avec quatre paramètres (parce que vous ne pouvez pas regarder à l'intérieur sans qu'il existe). Le premier, puisque nous le testons, nous devons évaluer tout le chemin à 4
, où nous nous rendons compte 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 6
étant stocké dans cet emplacement de mémoire, nous allons simplement stocker le code pour une évaluation ultérieure possible, (3+3)
. Cela deviendra un 6 seulement si quelqu'un le regarde.
Le troisième paramètre, cependant, a un !
en face de lui, donc est strictement évalué: (4+4)
est exécuté, et 8
est stocké dans cet emplacement de mémoire.
Le quatrième paramètre est également évalué strictement. Mais voici où cela devient un peu difficile: nous évaluons pas complètement, mais seulement à la forme de la 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 réellement Just (5+5)
, laissant le thunk à l'intérieur non évalué. C'est important à savoir, bien que je pense que toutes les implications de ceci vont au-delà de la portée de cette question.
Vous pouvez annoter arguments de la fonction de la même manière, si vous activez l'extension de la langue BangPatterns
:
f x !y = x*y
f (1+1) (2+2)
retournera thunk (1+1)*4
.
Je suspecte que ceci puisse être une question très commune; Je me souviens clairement me poser des questions sur la même chose moi-même, il y a longtemps. –