# Haskell

To use this language, use the class "language-haskell".

## Comments

    -- Single line comment
    {- Multi-line
    comment -}

## Strings and characters

    'a'
    '\n'
    '\^A'
    '\^]'
    '\NUL'
    '\23'
    '\o75'
    '\xFE'
    "Here is a backslant \\ as well as \137, \
        \a numeric escape character, and \^X, a control character."

## Numbers

    42
    123.456
    123.456e-789
    1e+3
    0o74
    0XAF

## Full example

    hGetLine h =
      wantReadableHandle_ "Data.ByteString.hGetLine" h $
        \ h_@Handle__{haByteBuffer} -> do
          flushCharReadBuffer h_
          buf <- readIORef haByteBuffer
          if isEmptyBuffer buf
             then fill h_ buf 0 []
             else haveBuf h_ buf 0 []
     where

      fill h_@Handle__{haByteBuffer,haDevice} buf len xss =
        len `seq` do
        (r,buf') <- Buffered.fillReadBuffer haDevice buf
        if r == 0
           then do writeIORef haByteBuffer buf{ bufR=0, bufL=0 }
                   if len > 0
                      then mkBigPS len xss
                      else ioe_EOF
           else haveBuf h_ buf' len xss

      haveBuf h_@Handle__{haByteBuffer}
              buf@Buffer{ bufRaw=raw, bufR=w, bufL=r }
              len xss =
        do
            off <- findEOL r w raw
            let new_len = len + off - r
            xs <- mkPS raw r off

          -- if eol == True, then off is the offset of the '\n'
          -- otherwise off == w and the buffer is now empty.
            if off /= w
                then do if (w == off + 1)
                                then writeIORef haByteBuffer buf{ bufL=0, bufR=0 }
                                else writeIORef haByteBuffer buf{ bufL = off + 1 }
                        mkBigPS new_len (xs:xss)
                else do
                     fill h_ buf{ bufL=0, bufR=0 } new_len (xs:xss)

      -- find the end-of-line character, if there is one
      findEOL r w raw
            | r == w = return w
            | otherwise =  do
                c <- readWord8Buf raw r
                if c == fromIntegral (ord '\n')
                    then return r -- NB. not r+1: don't include the '\n'
                    else findEOL (r+1) w raw

    mkPS :: RawBuffer Word8 -> Int -> Int -> IO ByteString
    mkPS buf start end =
     create len $ \p ->
       withRawBuffer buf $ \pbuf -> do
       copyBytes p (pbuf `plusPtr` start) len
     where
       len = end - start