Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which is the use of curly braces in Haskell?

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

like image 213
Dragno Avatar asked Jul 21 '12 09:07

Dragno


2 Answers

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.

like image 148
dflemstr Avatar answered Sep 26 '22 17:09

dflemstr


Curly braces is used in the syntax for record types. In this code, pattern matching is used to deconstruct the record type argument into its component fields.

like image 40
newacct Avatar answered Sep 25 '22 17:09

newacct