[Haskell-beginners] What does the "!n" mean?

John M. Dlugosz ngnr63q02 at sneakemail.com
Thu Mar 27 01:15:07 UTC 2014


I'm reading http://www.haskell.org/haskellwiki/IO_inside#inlinePerformIO and it shows a 
passage of code:

write :: Int -> (Ptr Word8 -> IO ()) -> Put ()
write !n body = Put $ \c buf@(Buffer fp o u l) ->
   if n <= l
     then write' c fp o u l
     else write' (flushOld c n fp o u) (newBuffer c n) 0 0 0

   where {-# NOINLINE write' #-}
         write' c !fp !o !u !l =
           -- warning: this is a tad hardcore
           inlinePerformIO
             (withForeignPtr fp
               (\p -> body $! (p `plusPtr` (o+u))))
           `seq` c () (Buffer fp o (u+n) (l-n))

I got as far as the second line, looking things up in this index 
<http://hackage.haskell.org/package/base-4.6.0.1/docs/doc-index.html>

But “write !n body = ⋯”
I understand write is defined to be a function taking an Int and another function,
but what does !n mean?  I went through the 2010 Report (BTW, the PDF is useless for 
searching for the ! character so I used the HTML version page-by-page) and found it used 
as a modifier for named record fields (it says "strict" but I think it's describing 
non-optional).
Then I went through the GHC users guide for language extensions, and found a reference in 
§7.2.1 without explanation but as an example where the difference between
	f x = let (Foo a b, w) = ..rhs.. in ..body..
and	f x = let !(Foo a b, w) = ..rhs.. in ..body..
is "you must make any such pattern-match strict".
Strict pattern matching is not mentioned elsewhere nor is it in the Haskell Report, so 
what am I missing?  I suspect that the usage I'm asking about is related.

The GHC users guide also mentions it again in §7.4.6 which I think is a reference to the 
same feature, “You can use strictness annotations, in the obvious places in the 
constructor type” but that's for use with a completely different extension (GADT types)

I also recognize the “@” mark as naming the entire variable rather than just the parts of 
the pattern matched, but “buf” is not actually used anywhere, so does it mean something 
different, or has other effects, or what?

Thanks in advance,
—John



More information about the Beginners mailing list