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

yi lu zhiwudazhanjiangshi at gmail.com
Thu Mar 27 01:26:26 UTC 2014


http://www.haskell.org/ghc/docs/7.6.3/html/users_guide/bang-patterns.html

Do you mean this?


On Thu, Mar 27, 2014 at 9:15 AM, John M. Dlugosz
<ngnr63q02 at sneakemail.com>wrote:

> I'm reading http://www.haskell.org/haskellwiki/IO_inside#inlinePerformIOand 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
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20140327/726c267d/attachment.html>


More information about the Beginners mailing list