[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