The code below
getSpareBuffer :: Handle__ -> IO (BufferMode, CharBuffer)
getSpareBuffer Handle__{haCharBuffer=ref,
haBuffers=spare_ref,
haBufferMode=mode}
= do
case mode of
NoBuffering -> return (mode, error "no buffer!")
_ -> do
bufs <- readIORef spare_ref
buf <- readIORef ref
case bufs of
BufferListCons b rest -> do
writeIORef spare_ref rest
return ( mode, emptyBuffer b (bufSize buf) WriteBuffer)
BufferListNil -> do
new_buf <- newCharBuffer (bufSize buf) WriteBuffer
return (mode, new_buf)
is from the GHC source code (ghc-7.4.1\libraries\base\GHC\IO\Handle\Text.hs). I want to know why the code uses curly braces in place of the arguments. And how the variables haCharBuffer, haBuffers, haBufferMode
take values from ref, spare_ref
and mode
. These values haven't defined.
Another fragment of code from GHC that needs clarification is this:
flushByteWriteBuffer :: Handle__ -> IO ()
flushByteWriteBuffer h_@Handle__{..} = do
bbuf <- readIORef haByteBuffer
when (not (isEmptyBuffer bbuf)) $ do
bbuf' <- Buffered.flushWriteBuffer haDevice bbuf
writeIORef haByteBuffer bbuf'
In the codefile ghc-7.4.1\libraries\base\GHC\IO\Handle\Internals.hs
Which is the use of dots inside the braces ({..}
)?
The Handle__
data type was probably defined with record syntax, like this:
data Handle__ =
Handle__
{ haCharBuffer :: IORef (...something...)
, haBuffers :: IORef (...something...)
, haBufferMode :: BufferMode
}
The curly braces are used to match against the fields of the record type. So, the declaration says: "Check if the argument is of the Handle__
constructor; in that case, store the value of haCharBuffer
in ref
, the value of haBuffers
in spare_ref
and the value of haBufferMode
in mode
"
When you write Handle__ {..}
it's the same thing as saying Handle__ { haCharBuffer = haCharBuffer, haBuffers = haBuffers, haBufferMode = haBufferMode }
; all the fields in the data structure are bound to their field names.