Действительно, это правильно.Мы можем видеть, что оценивается, используя :sprint
в GHCi
, который показывает нам, что были оценены thunks.
Без шаблонов взрыва:
λ data D = D Int
λ d1 = D 1
λ :sprint d1
d1 = _
λ f1 (D _) = 0
λ f1 d1
0
λ :sprint d1
d1 = <D> _ -- Only D evaluated
С внутренним шаблоном взрыва:
λ d2 = D 2
λ :sprint d2
d2 = _
λ f2 (D !_) = 0
λ f2 d2
0
λ :sprint d2
d2 = <D> 2 -- Everything evaluated
С шаблоном внешнего взрыва:
λ d3 = D 3
λ :sprint d3
d3 = _
λ f3 !(D _) = 0
λ f3 d3
0
λ :sprint d3
d3 = <D> _ -- Only D evaluated
С шаблоном внутреннего и внешнего взрыва:
λ d4 = D 4
λ :sprint d4
d4 = _
λ f4 !(D !_) = 0
λ f4 d4
0
λ :sprint d4
d4 = <D> 4 -- Everything evaluated
Из этого легко увидеть, что шаблоны!(D !_)
и (D !_)
эквивалентны, и более того, шаблоны вида !(D ...)
являются избыточными.