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: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 ofhaCharBufferinref, the value ofhaBuffersinspare_refand the value ofhaBufferModeinmode“When you write
Handle__ {..}it’s the same thing as sayingHandle__ { haCharBuffer = haCharBuffer, haBuffers = haBuffers, haBufferMode = haBufferMode }; all the fields in the data structure are bound to their field names.