
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-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).
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. -Brent