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

Brent Yorgey byorgey at seas.upenn.edu
Thu Mar 27 01:25:53 UTC 2014

On Wed, Mar 26, 2014 at 08:15:07PM -0500, John M. Dlugosz wrote:
> 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->
> 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).

No, strict does not mean optional vs. non-optional.  It has to do with
lazy evaluation.  In Haskell, by default, expressions are not
evaluated until their value is actually needed. Making something
strict means (to a first approximation) forcing it to be evaluated
right away, whether its value will be needed or not.  That is what all
the exclamation points mean, both in the code you cited above and the
examples you found; they can be used in a bunch of different contexts
but they always have to do with strictness.

Incidentally, that "IO inside" page is not particularly what I would
recommend for beginners to read!  It's like learning about spark plugs
and oil filters on your first day of driving school.

> 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?

Nope, you're right, it's simply not used.  Probably just an oversight
on the part of whoever wrote the code.  the buf@ could be deleted and
it wouldn't change anything.


More information about the Beginners mailing list