In Haskell, is there ever a situation where for a data type
{-# LANGUAGE BangPatterns #-}
import Control.DeepSeq
data D = D Int
the instance
instance NFData D where
rnf (D !_) = ()
can have a different effect than the instance with another outer !:
instance NFData D where
rnf !(D !_) = ()
My research:
- https://downloads.haskell.org/~ghc/8.6.3/docs/html/users_guide/glasgow_exts.html#bang-patterns-informal only talks about
letbindings (like this answer), which I think doesn't apply for function pattern matches like this. https://prime.haskell.org/wiki/BangPatterns#Thebasicidea says
A bang only really has an effect if it precedes a variable or wild-card pattern
and
putting a bang before a pattern that forces evaluation anyway does nothing
and I think
rnf (D _)already forces evaluation anyway- because it's like
rnf x = case x of D _ -> ...
- because it's like
- so
rnf !(D _)would have the same effect asrnf (D _) - and thus by substitution
rnf !(D !_)must have the same effect asrnf (D !_)
So I think no, these two are always equivalent, but I'm asking anyway to have one super clear answer to refer people to.