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

Mateusz Kowalczyk fuuzetsu at fuuzetsu.co.uk
Thu Mar 27 01:25:15 UTC 2014


On 27/03/14 01:15, 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-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)

It is in fact a strictness annotation which forces ‘n’ when matching on
it. It is an optimisation technique and if you're just starting out, I
would not worry about it too much. I would advise against putting those
on if you're not sure about the implications as they can make your
performance worse. GHC can in fact often add those itself.

I don't have any official reading for you but if you simply search for
‘Haskell strictness’ online, you should get quite a few links to Haskell
wiki, the Wikibook, Stack Overflow and some blogs.

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

It just seems that someone gave it a name and then didn't use it. It
does not have any extra meaning.

> 
> Thanks in advance,
> —John
> 
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
> 


-- 
Mateusz K.


More information about the Beginners mailing list