    module Data.Csv.Types
        (
        -- * Core CSV types
          Csv
        , Record
        , Header
        , Name
        , NamedRecord
        , Field
        , toNamedRecord

        -- * Header handling
        , HasHeader(..)
        ) where

    import qualified Data.ByteString as S
    import qualified Data.HashMap.Strict as HM
    import Data.Vector (Vector)
    import qualified Data.Vector as V

    -- | CSV data represented as a Haskell vector of vector of
    -- bytestrings.
    type Csv = Vector Record

    -- | A record corresponds to a single line in a CSV file.
    type Record = Vector Field

    -- | The header corresponds to the first line a CSV file. Not all CSV
    -- files have a header.
    type Header = Vector Name

    -- | A header has one or more names, describing the data in the column
    -- following the name.
    type Name = S.ByteString

    -- | A record corresponds to a single line in a CSV file, indexed by
    -- the column name rather than the column index.
    type NamedRecord = HM.HashMap S.ByteString S.ByteString

    -- | A single field within a record.
    type Field = S.ByteString

    -- | Convert a 'Record' to a 'NamedRecord' by attaching column names.
    -- The 'Header' and 'Record' must be of the same length.
    toNamedRecord :: Header -> Record -> NamedRecord
    toNamedRecord :: Header -> Header -> NamedRecord
    toNamedRecord hdr :: Header
    hdr v :: Header
    v = [(Name, Name)] -> NamedRecord
    forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
    HM.fromList ([(Name, Name)] -> NamedRecord)
    -> (Vector (Name, Name) -> [(Name, Name)])
    -> Vector (Name, Name)
    -> NamedRecord
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Vector (Name, Name) -> [(Name, Name)]
    forall a. Vector a -> [a]
    V.toList (Vector (Name, Name) -> NamedRecord)
    -> Vector (Name, Name) -> NamedRecord
    forall a b. (a -> b) -> a -> b
    $ Header -> Header -> Vector (Name, Name)
    forall a b. Vector a -> Vector b -> Vector (a, b)
    V.zip Header
    hdr Header
    v

    -- | Is the CSV data preceded by a header?
    data HasHeader = HasHeader  -- ^ The CSV data is preceded by a header
                   | NoHeader   -- ^ The CSV data is not preceded by a header