É uma declaração de rigor. Basicamente, isso significa que ele deve ser avaliado para o que é chamado "formulário normal de cabeça fraca" quando o valor da estrutura de dados é criado. Vejamos um exemplo, para que possamos ver exatamente o que isso significa:
data Foo = Foo Int Int !Int !(Maybe Int)
f = Foo (2+2) (3+3) (4+4) (Just (5+5))
A função f
acima, quando avaliada, retornará um "thunk": ou seja, o código a ser executado para descobrir seu valor. Nesse ponto, um Foo ainda nem existe, apenas o código.
Mas em algum momento alguém pode tentar olhar dentro dele, provavelmente através de uma correspondência de padrões:
case f of
Foo 0 _ _ _ -> "first arg is zero"
_ -> "first arge is something else"
Isso vai executar código suficiente para fazer o que precisa, e não mais. Portanto, ele criará um Foo com quatro parâmetros (porque você não pode olhar dentro dele sem que ele exista). A primeira, como estamos testando, precisamos avaliar todo o caminho para4
em que percebemos que não corresponde.
O segundo não precisa ser avaliado, porque não estamos testando. Portanto, em vez de 6
ser armazenado nesse local de memória, apenas armazenaremos o código para uma possível avaliação posterior (3+3)
. Isso só se tornará um 6 se alguém olhar para ele.
O terceiro parâmetro, no entanto, tem um !
na frente, portanto é estritamente avaliado: (4+4)
é executado e 8
é armazenado nesse local de memória.
O quarto parâmetro também é rigorosamente avaliado. Mas aqui é onde fica um pouco complicado: estamos avaliando não totalmente, mas apenas a forma normal da cabeça fraca. Isso significa que descobrimos se é Nothing
ou Just
algo assim e armazenamos isso, mas não vamos mais longe. Isso significa que não armazenamos, Just 10
mas Just (5+5)
, na verdade , deixando o thunk dentro de uma avaliação. É importante saber, embora eu pense que todas as implicações disso vão além do escopo desta questão.
Você pode anotar argumentos de função da mesma maneira, se ativar a BangPatterns
extensão de idioma:
f x !y = x*y
f (1+1) (2+2)
retornará o thunk (1+1)*4
.