Which is the use of curly braces in Haskell?

Dragno picture Dragno · Jul 21, 2012 · Viewed 8.3k times · Source

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 ({..})?

Answer

dflemstr picture dflemstr · Jul 21, 2012

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.