title: Do inner bang patterns always force outer constructors in Haskell?
body: <p>In Haskell, is there ever a situation where for a data type</p>
  
  <pre><code>{-# LANGUAGE BangPatterns #-}
  import Control.DeepSeq
  
  data D = D Int
  </code></pre>
  
  <p>the instance</p>
  
  <pre><code>instance NFData D where
    rnf (D !_) = ()
  </code></pre>
  
  <p>can have a different effect than the instance with another outer <code>!</code>:</p>
  
  <pre><code>instance NFData D where
    rnf !(D !_) = ()
  </code></pre>
  
  <p>My research:</p>
  
  <ul>
  <li><a href="https://downloads.haskell.org/~ghc/8.6.3/docs/html/users_guide/glasgow_exts.html#bang-patterns-informal" rel="noreferrer">https://downloads.haskell.org/~ghc/8.6.3/docs/html/users_guide/glasgow_exts.html#bang-patterns-informal</a> only talks about <code>let</code> bindings (like <a href="https://stackoverflow.com/questions/6509399/tuple-bang-patterns">this</a> answer), which I think doesn't apply for function pattern matches like this.</li>
  <li><p><a href="https://prime.haskell.org/wiki/BangPatterns#Thebasicidea" rel="noreferrer">https://prime.haskell.org/wiki/BangPatterns#Thebasicidea</a> says</p>
  
  <blockquote>
    <p>A bang only really has an effect if it precedes a variable or wild-card pattern</p>
  </blockquote>
  
  <p>and</p>
  
  <blockquote>
    <p>putting a bang before a pattern that forces evaluation anyway does nothing</p>
  </blockquote>
  
  <p>and I think</p>
  
  <ul>
  <li><code>rnf (D _)</code> already forces evaluation anyway
  
  <ul>
  <li>because it's like <code>rnf x = case x of D _ -&gt; ...</code></li>
  </ul></li>
  <li>so <code>rnf !(D _)</code> would have the same effect as <code>rnf (D _)</code></li>
  <li>and thus by substitution <code>rnf !(D !_)</code> must have the same effect as <code>rnf (D !_)</code></li>
  </ul></li>
  </ul>
  
  <p>So I think <em>no, these two are always equivalent</em>, but I'm asking anyway to have one super clear answer to refer people to.</p>