I am reading the source code of Data.Map, and I find that !() is used in the data constructor of data Map k a
.
data Map k a = Tip
| Bin {-# UNPACK #-} !Size !k a !(Map k a) !(Map k a)
I find that the !( )
does not affect how the patten matching against the data. In the function of mapWithKey, the patten matching is still for 5 things. So I do not consider it as a operator.
mapWithKey f (Bin sx kx x l r)
After googleing, I found that the !( )
may be related to -XBangPatterns
which is used for lazy evalution. Am I right ? Or is it for other purpose?
!
in data type declarations is used to indicate strictness. If we search for it on Hoogle, we see a link to keyword !, which explains the behavior. The Report defines the exact behavior.
In data Foo = Foo ... !T ...
, the constructor Foo
forces its argument, i.e. Foo ... x ... = x `seq` RealFoo ... x ...
. where RealFoo
is the constructor you would get without the !
.
{-# UNPACK #-}
is a GHC extension that means the Size
(i.e. Int
) is stored unboxed, directly as part of the data type.
In a data constructor ! indicates the arguments are evaluated as the type is constructed. This forces functions to be evaluated and helps you control the space requirements of your application.
The high-performance Haskell slides cover this in more detail.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With