Data.Csv

cassava-0.5.3.2: A CSV parsing and encoding library

Safe Haskell | None
Language | Haskell2010

Data.Csv

Contents

- Usage examples
  - Encoding and decoding custom data types
    - Index-based record conversion
    - Name-based record conversion
  - Reading/writing CSV files
- Treating CSV data as opaque byte strings
- Custom type conversions for fields
  - Dealing with bad data
- Encoding and decoding
  - Encoding and decoding options
- Core CSV types
- Type conversion
  - Index-based record conversion
  - Name-based record conversion
  - Field conversion
  - `Generic` record conversion
    - `Generic` type conversion options
    - `Generic` type conversion class name

Description

This module implements encoding and decoding of comma-separated values (CSV) data. The implementation is RFC 4180 compliant, with the following extensions:

- Empty lines are ignored.
- Non-escaped fields may contain any characters except double-quotes, commas, carriage returns, and newlines.
- Escaped fields may contain any characters (but double-quotes need to be escaped).

Synopsis

- data HasHeader
  - = HasHeader
  - | NoHeader
- decode :: FromRecord a => HasHeader -> ByteString -> Either String (Vector a)
- decodeByName :: FromNamedRecord a => ByteString -> Either String (Header, Vector a)
- encode :: ToRecord a => [a] -> ByteString
- encodeByName :: ToNamedRecord a => Header -> [a] -> ByteString
- encodeDefaultOrderedByName :: (DefaultOrdered a, ToNamedRecord a) => [a] -> ByteString
- class DefaultOrdered a where
  - headerOrder :: a -> Header
- data DecodeOptions = DecodeOptions {
  - decDelimiter :: !Word8
  }
- defaultDecodeOptions :: DecodeOptions
- decodeWith :: FromRecord a => DecodeOptions -> HasHeader -> ByteString -> Either String (Vector a)
- decodeWithP :: (Record -> Parser a) -> DecodeOptions -> HasHeader -> ByteString -> Either String (Vector a)
- decodeByNameWith :: FromNamedRecord a => DecodeOptions -> ByteString -> Either String (Header, Vector a)
- decodeByNameWithP :: (NamedRecord -> Parser a) -> DecodeOptions -> ByteString -> Either String (Header, Vector a)
- data EncodeOptions = EncodeOptions {
  - encDelimiter :: !Word8
  - encUseCrLf :: !Bool
  - encIncludeHeader :: !Bool
  - encQuoting :: !Quoting
  }
- data Quoting
  - = QuoteNone
  - | QuoteMinimal
  - | QuoteAll
- defaultEncodeOptions :: EncodeOptions
- encodeWith :: ToRecord a => EncodeOptions -> [a] -> ByteString
- encodeByNameWith :: ToNamedRecord a => EncodeOptions -> Header -> [a] -> ByteString
- encodeDefaultOrderedByNameWith :: (DefaultOrdered a, ToNamedRecord a) => EncodeOptions -> [a] -> ByteString
- type Csv = Vector Record
- type Record = Vector Field
- type Field = ByteString
- type Header = Vector Name
- type Name = ByteString
- type NamedRecord = HashMap ByteString ByteString
- class FromRecord a where
  - parseRecord :: Record -> Parser a
- data Parser a
- runParser :: Parser a -> Either String a
- index :: FromField a => Record -> Int -> Parser a
- (.!) :: FromField a => Record -> Int -> Parser a
- unsafeIndex :: FromField a => Record -> Int -> Parser a
- class ToRecord a where
  - toRecord :: a -> Record
- record :: [ByteString] -> Record
- newtype Only a = Only {
  - fromOnly :: a
  }
- class FromNamedRecord a where
  - parseNamedRecord :: NamedRecord -> Parser a
- lookup :: FromField a => NamedRecord -> ByteString -> Parser a
- (.:) :: FromField a => NamedRecord -> ByteString -> Parser a
- class ToNamedRecord a where
  - toNamedRecord :: a -> NamedRecord
- namedRecord :: [(ByteString, ByteString)] -> NamedRecord
- namedField :: ToField a => ByteString -> a -> (ByteString, ByteString)
- (.=) :: ToField a => ByteString -> a -> (ByteString, ByteString)
- header :: [ByteString] -> Header
- class FromField a where
  - parseField :: Field -> Parser a
- class ToField a where
  - toField :: a -> Field
- genericParseRecord :: (Generic a, GFromRecord (Rep a)) => Options -> Record -> Parser a
- genericToRecord :: (Generic a, GToRecord (Rep a) Field) => Options -> a -> Record
- genericParseNamedRecord :: (Generic a, GFromNamedRecord (Rep a)) => Options -> NamedRecord -> Parser a
- genericToNamedRecord :: (Generic a, GToRecord (Rep a) (ByteString, ByteString)) => Options -> a -> NamedRecord
- genericHeaderOrder :: (Generic a, GToNamedRecordHeader (Rep a)) => Options -> a -> Header
- data Options
- defaultOptions :: Options
- fieldLabelModifier :: Options -> String -> String
- class GFromRecord (f :: k -> Type)
- class GToRecord (a :: k -> Type) f
- class GFromNamedRecord (f :: k -> Type)
- class GToNamedRecordHeader (a :: k -> Type)

# Usage examples

Encoding standard Haskell types:

    >>> :set -XOverloadedStrings
    >>> import Data.Text (Text)
    >>> encode [("John" :: Text, 27 :: Int), ("Jane", 28)]
    "John,27\r\nJane,28\r\n"

Since we enabled the -XOverloadedStrings extension, string literals are polymorphic and we have to supply a type signature as the compiler couldn't deduce which string type (i.e. `String`, `ShortText`, or `Text`) we want to use. In most cases type inference will infer the type from the context and you can omit type signatures.

Decoding standard Haskell types:

    >>> import Data.Vector (Vector)
    >>> decode NoHeader "John,27\r\nJane,28\r\n" :: Either String (Vector (Text, Int))
    Right [("John",27),("Jane",28)]

We pass `NoHeader` as the first argument to indicate that the CSV input data isn't preceded by a header.

In practice, the return type of `decode` rarely needs to be given, as it can often be inferred from the context.

## Encoding and decoding custom data types

To encode and decode your own data types you need to defined instances of either `ToRecord` and `FromRecord` or `ToNamedRecord` and `FromNamedRecord`. The former is used for encoding/decoding using the column index and the latter using the column name.

There are two ways to to define these instances, either by manually defining them or by using GHC generics to derive them automatically.

### Index-based record conversion

GHC.Generics-derived:

    {-# LANGUAGE DeriveGeneric #-}

    import Data.Text    (Text)
    import GHC.Generics (Generic)

    data Person = Person { name :: !Text , salary :: !Int }
        deriving (Generic, Show)

    instance FromRecord Person
    instance ToRecord Person

Manually defined:

    import Control.Monad (mzero)

    data Person = Person { name :: !Text , salary :: !Int }
        deriving (Show)

    instance FromRecord Person where
        parseRecord v
            | length v == 2 = Person <$> v .! 0 <*> v .! 1
            | otherwise     = mzero
    instance ToRecord Person where
        toRecord (Person name' age') = record [
            toField name', toField age']

We can now use e.g. `encode` and `decode` to encode and decode our data type.

Encoding:

    >>> encode [Person ("John" :: Text) 27]
    "John,27\r\n"

Decoding:

    >>> decode NoHeader "John,27\r\n" :: Either String (Vector Person)
    Right [Person {name = "John", salary = 27}]

### Name-based record conversion

GHC.Generics-derived:

    {-# LANGUAGE DeriveGeneric #-}

    import Data.Text    (Text)
    import GHC.Generics (Generic)

    data Person = Person { name :: !Text , salary :: !Int }
        deriving (Generic, Show)

    instance FromNamedRecord Person
    instance ToNamedRecord Person
    instance DefaultOrdered Person

Manually defined:

    data Person = Person { name :: !Text , salary :: !Int }
        deriving (Show)

    instance FromNamedRecord Person where
        parseNamedRecord m = Person <$> m .: "name" <*> m .: "salary"
    instance ToNamedRecord Person where
        toNamedRecord (Person name salary) = namedRecord [
            "name" .= name, "salary" .= salary]
    instance DefaultOrdered Person where
        headerOrder _ = header ["name", "salary"]

We can now use e.g. `encodeDefaultOrderedByName` (or `encodeByName` with an explicit header order) and `decodeByName` to encode and decode our data type.

Encoding:

    >>> encodeDefaultOrderedByName [Person ("John" :: Text) 27]
    "name,salary\r\nJohn,27\r\n"

Decoding:

    >>> decodeByName "name,salary\r\nJohn,27\r\n" :: Either String (Header, Vector Person)
    Right (["name","salary"],[Person {name = "John", salary = 27}])

## Reading/writing CSV files

Demonstration of reading from a CSV file/ writing to a CSV file using the incremental API:

    {-# LANGUAGE BangPatterns      #-}
    {-# LANGUAGE DeriveGeneric     #-}
    {-# LANGUAGE LambdaCase        #-}
    {-# LANGUAGE OverloadedStrings #-}

    -- from base
    import GHC.Generics
    import System.IO
    import System.Exit (exitFailure)
    -- from bytestring
    import Data.ByteString (ByteString, hGetSome, empty)
    import qualified Data.ByteString.Lazy as BL
    -- from cassava
    import Data.Csv.Incremental
    import Data.Csv (FromRecord, ToRecord)

    data Person = Person
      { name :: !ByteString
      , age  :: !Int
      } deriving (Show, Eq, Generic)

    instance FromRecord Person
    instance ToRecord Person

    persons :: [Person]
    persons = [Person "John Doe" 19, Person "Smith" 20]

    writeToFile :: IO ()
    writeToFile = do
      BL.writeFile "persons.csv" $ encode $
        foldMap encodeRecord persons

    feed :: (ByteString -> Parser Person) -> Handle -> IO (Parser Person)
    feed k csvFile = do
      hIsEOF csvFile >>= \case
        True  -> return $ k empty
        False -> k <$> hGetSome csvFile 4096

    readFromFile :: IO ()
    readFromFile = do
      withFile "persons.csv" ReadMode $ \ csvFile -> do
        let loop !_ (Fail _ errMsg) = do putStrLn errMsg; exitFailure
            loop acc (Many rs k)    = loop (acc <> rs) =<< feed k csvFile
            loop acc (Done rs)      = print (acc <> rs)
        loop [] (decode NoHeader)

    main :: IO ()
    main = do
      writeToFile
      readFromFile

# Treating CSV data as opaque byte strings

Sometimes you might want to work with a CSV file which contents is unknown to you. For example, you might want remove the second column of a file without knowing anything about its content. To parse a CSV file to a generic representation, just convert each record to a ``Vector` `ByteString`` value, like so:

    >>> import Data.ByteString (ByteString)
    >>> decode NoHeader "John,27\r\nJane,28\r\n" :: Either String (Vector (Vector ByteString))
    Right [["John","27"],["Jane","28"]]

As the example output above shows, all the fields are returned as uninterpreted `ByteString` values.

# Custom type conversions for fields

Most of the time the existing `FromField` and `ToField` instances do what you want. However, if you need to parse a different format (e.g. hex) but use a type (e.g. `Int`) for which there's already a `FromField` instance, you need to use a `newtype`. Example:

    newtype Hex = Hex Int

    parseHex :: ByteString -> Parser Int
    parseHex = ...

    instance FromField Hex where
        parseField s = Hex <$> parseHex s

Other than giving an explicit type signature, you can pattern match on the `newtype` constructor to indicate which type conversion you want to have the library use:

    case decode NoHeader "0xff,0xaa\r\n0x11,0x22\r\n" of
        Left err -> putStrLn err
        Right v  -> forM_ v $ \ (Hex val1, Hex val2) ->
            print (val1, val2)

If a field might be in one several different formats, you can use a newtype to normalize the result:

    newtype HexOrDecimal = HexOrDecimal Int

    instance FromField DefaultToZero where
        parseField s = case runParser (parseField s :: Parser Hex) of
            Left err -> HexOrDecimal <$> parseField s  -- Uses Int instance
            Right n  -> pure $ HexOrDecimal n

You can use the unit type, `()`, to ignore a column. The `parseField` method for `()` doesn't look at the `Field` and thus always decodes successfully. Note that it lacks a corresponding `ToField` instance. Example:

    case decode NoHeader "foo,1\r\nbar,22" of
        Left  err -> putStrLn err
        Right v   -> forM_ v $ \ ((), i) -> print (i :: Int)

## Dealing with bad data

If your input might contain invalid fields, you can write a custom `FromField` instance to deal with them. Example:

    newtype DefaultToZero = DefaultToZero Int

    instance FromField DefaultToZero where
        parseField s = case runParser (parseField s) of
            Left err -> pure $ DefaultToZero 0
            Right n  -> pure $ DefaultToZero n

# Encoding and decoding

Encoding and decoding is a two step process. To encode a value, it is first converted to a generic representation, using either `ToRecord` or `ToNamedRecord`. The generic representation is then encoded as CSV data. To decode a value the process is reversed and either `FromRecord` or `FromNamedRecord` is used instead. Both these steps are combined in the `encode` and `decode` functions.

data HasHeader #

Is the CSV data preceded by a header?

Constructors

HasHeader | The CSV data is preceded by a header
NoHeader | The CSV data is not preceded by a header

decode #

Arguments

:: FromRecord a |
=> HasHeader | Data contains header that should be skipped
-> ByteString | CSV data
-> Either String (Vector a) |

Efficiently deserialize CSV records from a lazy `ByteString`. If this fails due to incomplete or invalid input, ``Left` msg` is returned. Equivalent to ``decodeWith` `defaultDecodeOptions``.

decodeByName #

Arguments

:: FromNamedRecord a |
=> ByteString | CSV data
-> Either String (Header, Vector a) |

Efficiently deserialize CSV records from a lazy `ByteString`. If this fails due to incomplete or invalid input, ``Left` msg` is returned. The data is assumed to be preceded by a header. Equivalent to ``decodeByNameWith` `defaultDecodeOptions``.

encode :: ToRecord a => [a] -> ByteString #

Efficiently serialize CSV records as a lazy `ByteString`.

encodeByName :: ToNamedRecord a => Header -> [a] -> ByteString #

Efficiently serialize CSV records as a lazy `ByteString`. The header is written before any records and dictates the field order.

encodeDefaultOrderedByName :: (DefaultOrdered a, ToNamedRecord a) => [a] -> ByteString #

Like `encodeByName`, but header and field order is dictated by the `header` method.

class DefaultOrdered a where #

A type that has a default field order when converted to CSV. This class lets you specify how to get the headers to use for a record type that's an instance of `ToNamedRecord`.

To derive an instance, the type is required to only have one constructor and that constructor must have named fields (also known as selectors) for all fields.

Right: `data Foo = Foo { foo :: !Int }`

Wrong: `data Bar = Bar Int`

If you try to derive an instance using GHC generics and your type doesn't have named fields, you will get an error along the lines of:

    <interactive>:9:10:
        No instance for (DefaultOrdered (M1 S NoSelector (K1 R Char) ()))
          arising from a use of ‘Data.Csv.Conversion.$gdmheader’
        In the expression: Data.Csv.Conversion.$gdmheader
        In an equation for ‘header’:
            header = Data.Csv.Conversion.$gdmheader
        In the instance declaration for ‘DefaultOrdered Foo’

Minimal complete definition

Nothing

Methods

headerOrder :: a -> Header #

The header order for this record. Should include the names used in the `NamedRecord` returned by `toNamedRecord`. Pass `undefined` as the argument, together with a type annotation e.g. ``headerOrder` (`undefined` :: MyRecord)`.

default headerOrder :: (Generic a, GToNamedRecordHeader (Rep a)) => a -> Header #

## Encoding and decoding options

These functions can be used to control how data is encoded and decoded. For example, they can be used to encode data in a tab-separated format instead of in a comma-separated format.

data DecodeOptions #

Options that controls how data is decoded. These options can be used to e.g. decode tab-separated data instead of comma-separated data.

To avoid having your program stop compiling when new fields are added to `DecodeOptions`, create option records by overriding values in `defaultDecodeOptions`. Example:

    myOptions = defaultDecodeOptions {
          decDelimiter = fromIntegral (ord '\t')
        }

Constructors

DecodeOptions |
Fields decDelimiter :: !Word8 Field delimiter.

#### Instances

Instances details

Show DecodeOptions # |
Instance details Defined in Data.Csv.Parser Methods showsPrec :: Int -> DecodeOptions -> ShowS # show :: DecodeOptions -> String # showList :: [DecodeOptions] -> ShowS #
Eq DecodeOptions # |
Instance details Defined in Data.Csv.Parser Methods (==) :: DecodeOptions -> DecodeOptions -> Bool # (/=) :: DecodeOptions -> DecodeOptions -> Bool #

defaultDecodeOptions :: DecodeOptions #

Decoding options for parsing CSV files.

decodeWith #

Arguments

:: FromRecord a |
=> DecodeOptions | Decoding options
-> HasHeader | Data contains header that should be skipped
-> ByteString | CSV data
-> Either String (Vector a) |

Like `decode`, but lets you customize how the CSV data is parsed.

decodeWithP #

Arguments

:: (Record -> Parser a) | Custom parser function
-> DecodeOptions | Decoding options
-> HasHeader | Data contains header that should be skipped
-> ByteString | CSV data
-> Either String (Vector a) |

Like `decodeWith'`, but lets you specify a parser function.

Since: 0.5.2.0

decodeByNameWith #

Arguments

:: FromNamedRecord a |
=> DecodeOptions | Decoding options
-> ByteString | CSV data
-> Either String (Header, Vector a) |

Like `decodeByName`, but lets you customize how the CSV data is parsed.

decodeByNameWithP #

Arguments

:: (NamedRecord -> Parser a) | Custom parser function
-> DecodeOptions | Decoding options
-> ByteString | CSV data
-> Either String (Header, Vector a) |

Like `decodeByNameWith`, but lets you specify a parser function.

Since: 0.5.2.0

data EncodeOptions #

Options that controls how data is encoded. These options can be used to e.g. encode data in a tab-separated format instead of in a comma-separated format.

To avoid having your program stop compiling when new fields are added to `EncodeOptions`, create option records by overriding values in `defaultEncodeOptions`. Example:

    myOptions = defaultEncodeOptions {
          encDelimiter = fromIntegral (ord '\t')
        }

N.B. The `encDelimiter` must not be the quote character (i.e. `"`) or one of the record separator characters (i.e. `\n` or `\r`).

Constructors

EncodeOptions |
Fields encDelimiter :: !Word8 Field delimiter. encUseCrLf :: !Bool Record separator selection. `True` for CRLF (`\r\n`) and `False` for LF (`\n`). encIncludeHeader :: !Bool Include a header row when encoding `ToNamedRecord` instances. encQuoting :: !Quoting What kind of quoting should be applied to text fields.

#### Instances

Instances details

Show EncodeOptions # |
Instance details Defined in Data.Csv.Encoding Methods showsPrec :: Int -> EncodeOptions -> ShowS # show :: EncodeOptions -> String # showList :: [EncodeOptions] -> ShowS #
Eq EncodeOptions # |
Instance details Defined in Data.Csv.Encoding Methods (==) :: EncodeOptions -> EncodeOptions -> Bool # (/=) :: EncodeOptions -> EncodeOptions -> Bool #

data Quoting #

Should quoting be applied to fields, and at which level?

Constructors

QuoteNone | No quotes.
QuoteMinimal | Quotes according to RFC 4180.
QuoteAll | Always quote.

#### Instances

Instances details

Show Quoting # |
Instance details Defined in Data.Csv.Encoding Methods showsPrec :: Int -> Quoting -> ShowS # show :: Quoting -> String # showList :: [Quoting] -> ShowS #
Eq Quoting # |
Instance details Defined in Data.Csv.Encoding Methods (==) :: Quoting -> Quoting -> Bool # (/=) :: Quoting -> Quoting -> Bool #

defaultEncodeOptions :: EncodeOptions #

Encoding options for CSV files.

encodeWith :: ToRecord a => EncodeOptions -> [a] -> ByteString #

Like `encode`, but lets you customize how the CSV data is encoded.

encodeByNameWith :: ToNamedRecord a => EncodeOptions -> Header -> [a] -> ByteString #

Like `encodeByName`, but lets you customize how the CSV data is encoded.

encodeDefaultOrderedByNameWith :: (DefaultOrdered a, ToNamedRecord a) => EncodeOptions -> [a] -> ByteString #

Like `encodeDefaultOrderedByNameWith`, but lets you customize how the CSV data is encoded.

# Core CSV types

type Csv = Vector Record #

CSV data represented as a Haskell vector of vector of bytestrings.

type Record = Vector Field #

A record corresponds to a single line in a CSV file.

type Field = ByteString #

A single field within a record.

type Header = Vector Name #

The header corresponds to the first line a CSV file. Not all CSV files have a header.

type Name = ByteString #

A header has one or more names, describing the data in the column following the name.

type NamedRecord = HashMap ByteString ByteString #

A record corresponds to a single line in a CSV file, indexed by the column name rather than the column index.

# Type conversion

There are two ways to convert CSV records to and from and user-defined data types: index-based conversion and name-based conversion.

## Index-based record conversion

Index-based conversion lets you convert CSV records to and from user-defined data types by referring to a field's position (its index) in the record. The first column in a CSV file is given index 0, the second index 1, and so on.

class FromRecord a where #

A type that can be converted from a single CSV record, with the possibility of failure.

When writing an instance, use `empty`, `mzero`, or `fail` to make a conversion fail, e.g. if a `Record` has the wrong number of columns.

Given this example data:

    John,56
    Jane,55

here's an example type and instance:

    data Person = Person { name :: !Text, age :: !Int }

    instance FromRecord Person where
        parseRecord v
            | length v == 2 = Person <$>
                              v .! 0 <*>
                              v .! 1
            | otherwise     = mzero

Minimal complete definition

Nothing

Methods

parseRecord :: Record -> Parser a #

default parseRecord :: (Generic a, GFromRecord (Rep a)) => Record -> Parser a #

#### Instances

Instances details

FromField a => FromRecord (Only a) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (Only a) #
FromField a => FromRecord (Vector a) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (Vector a) #
(FromField a, Unbox a) => FromRecord (Vector a) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (Vector a) #
FromField a => FromRecord [a] # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser [a] #
(FromField a, FromField b) => FromRecord (a, b) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (a, b) #
(FromField a, FromField b, FromField c) => FromRecord (a, b, c) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (a, b, c) #
(FromField a, FromField b, FromField c, FromField d) => FromRecord (a, b, c, d) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (a, b, c, d) #
(FromField a, FromField b, FromField c, FromField d, FromField e) => FromRecord (a, b, c, d, e) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (a, b, c, d, e) #
(FromField a, FromField b, FromField c, FromField d, FromField e, FromField f) => FromRecord (a, b, c, d, e, f) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (a, b, c, d, e, f) #
(FromField a, FromField b, FromField c, FromField d, FromField e, FromField f, FromField g) => FromRecord (a, b, c, d, e, f, g) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (a, b, c, d, e, f, g) #
(FromField a, FromField b, FromField c, FromField d, FromField e, FromField f, FromField g, FromField h) => FromRecord (a, b, c, d, e, f, g, h) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (a, b, c, d, e, f, g, h) #
(FromField a, FromField b, FromField c, FromField d, FromField e, FromField f, FromField g, FromField h, FromField i) => FromRecord (a, b, c, d, e, f, g, h, i) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (a, b, c, d, e, f, g, h, i) #
(FromField a, FromField b, FromField c, FromField d, FromField e, FromField f, FromField g, FromField h, FromField i, FromField j) => FromRecord (a, b, c, d, e, f, g, h, i, j) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (a, b, c, d, e, f, g, h, i, j) #
(FromField a, FromField b, FromField c, FromField d, FromField e, FromField f, FromField g, FromField h, FromField i, FromField j, FromField k) => FromRecord (a, b, c, d, e, f, g, h, i, j, k) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (a, b, c, d, e, f, g, h, i, j, k) #
(FromField a, FromField b, FromField c, FromField d, FromField e, FromField f, FromField g, FromField h, FromField i, FromField j, FromField k, FromField l) => FromRecord (a, b, c, d, e, f, g, h, i, j, k, l) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (a, b, c, d, e, f, g, h, i, j, k, l) #
(FromField a, FromField b, FromField c, FromField d, FromField e, FromField f, FromField g, FromField h, FromField i, FromField j, FromField k, FromField l, FromField m) => FromRecord (a, b, c, d, e, f, g, h, i, j, k, l, m) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (a, b, c, d, e, f, g, h, i, j, k, l, m) #
(FromField a, FromField b, FromField c, FromField d, FromField e, FromField f, FromField g, FromField h, FromField i, FromField j, FromField k, FromField l, FromField m, FromField n) => FromRecord (a, b, c, d, e, f, g, h, i, j, k, l, m, n) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (a, b, c, d, e, f, g, h, i, j, k, l, m, n) #
(FromField a, FromField b, FromField c, FromField d, FromField e, FromField f, FromField g, FromField h, FromField i, FromField j, FromField k, FromField l, FromField m, FromField n, FromField o) => FromRecord (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) #

data Parser a #

Conversion of a field to a value might fail e.g. if the field is malformed. This possibility is captured by the `Parser` type, which lets you compose several field conversions together in such a way that if any of them fail, the whole record conversion fails.

#### Instances

Instances details

Alternative Parser # |
Instance details Defined in Data.Csv.Conversion Methods empty :: Parser a # (<|>) :: Parser a -> Parser a -> Parser a # some :: Parser a -> Parser [a] # many :: Parser a -> Parser [a] #
Applicative Parser # |
Instance details Defined in Data.Csv.Conversion Methods pure :: a -> Parser a # (<*>) :: Parser (a -> b) -> Parser a -> Parser b # liftA2 :: (a -> b -> c) -> Parser a -> Parser b -> Parser c # (*>) :: Parser a -> Parser b -> Parser b # (<*) :: Parser a -> Parser b -> Parser a #
Functor Parser # |
Instance details Defined in Data.Csv.Conversion Methods fmap :: (a -> b) -> Parser a -> Parser b # (<$) :: a -> Parser b -> Parser a #
Monad Parser # |
Instance details Defined in Data.Csv.Conversion Methods (>>=) :: Parser a -> (a -> Parser b) -> Parser b # (>>) :: Parser a -> Parser b -> Parser b # return :: a -> Parser a #
MonadPlus Parser # |
Instance details Defined in Data.Csv.Conversion Methods mzero :: Parser a # mplus :: Parser a -> Parser a -> Parser a #
MonadFail Parser # | Since: 0.5.0.0
Instance details Defined in Data.Csv.Conversion Methods fail :: String -> Parser a #
Monoid (Parser a) # |
Instance details Defined in Data.Csv.Conversion Methods mempty :: Parser a # mappend :: Parser a -> Parser a -> Parser a # mconcat :: [Parser a] -> Parser a #
Semigroup (Parser a) # | Since: 0.5.0.0
Instance details Defined in Data.Csv.Conversion Methods (<>) :: Parser a -> Parser a -> Parser a # sconcat :: NonEmpty (Parser a) -> Parser a # stimes :: Integral b => b -> Parser a -> Parser a #

runParser :: Parser a -> Either String a #

Run a `Parser`, returning either ``Left` errMsg` or ``Right` result`. Forces the value in the `Left` or `Right` constructors to weak head normal form.

You most likely won't need to use this function directly, but it's included for completeness.

index :: FromField a => Record -> Int -> Parser a #

Retrieve the nth field in the given record. The result is `empty` if the value cannot be converted to the desired type. Raises an exception if the index is out of bounds.

`index` is a simple convenience function that is equivalent to ``parseField` (v `!` idx)`. If you're certain that the index is not out of bounds, using `unsafeIndex` is somewhat faster.

(.!) :: FromField a => Record -> Int -> Parser a infixl 9 #

Alias for `index`.

unsafeIndex :: FromField a => Record -> Int -> Parser a #

Like `index` but without bounds checking.

class ToRecord a where #

A type that can be converted to a single CSV record.

An example type and instance:

    data Person = Person { name :: !Text, age :: !Int }

    instance ToRecord Person where
        toRecord (Person name age) = record [
            toField name, toField age]

Outputs data on this form:

    John,56
    Jane,55

Minimal complete definition

Nothing

Methods

toRecord :: a -> Record #

Convert a value to a record.

default toRecord :: (Generic a, GToRecord (Rep a) Field) => a -> Record #

#### Instances

Instances details

ToField a => ToRecord (Only a) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: Only a -> Record #
ToField a => ToRecord (Vector a) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: Vector a -> Record #
(ToField a, Unbox a) => ToRecord (Vector a) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: Vector a -> Record #
ToField a => ToRecord [a] # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: [a] -> Record #
(ToField a, ToField b) => ToRecord (a, b) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: (a, b) -> Record #
(ToField a, ToField b, ToField c) => ToRecord (a, b, c) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: (a, b, c) -> Record #
(ToField a, ToField b, ToField c, ToField d) => ToRecord (a, b, c, d) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: (a, b, c, d) -> Record #
(ToField a, ToField b, ToField c, ToField d, ToField e) => ToRecord (a, b, c, d, e) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: (a, b, c, d, e) -> Record #
(ToField a, ToField b, ToField c, ToField d, ToField e, ToField f) => ToRecord (a, b, c, d, e, f) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: (a, b, c, d, e, f) -> Record #
(ToField a, ToField b, ToField c, ToField d, ToField e, ToField f, ToField g) => ToRecord (a, b, c, d, e, f, g) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: (a, b, c, d, e, f, g) -> Record #
(ToField a, ToField b, ToField c, ToField d, ToField e, ToField f, ToField g, ToField h) => ToRecord (a, b, c, d, e, f, g, h) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: (a, b, c, d, e, f, g, h) -> Record #
(ToField a, ToField b, ToField c, ToField d, ToField e, ToField f, ToField g, ToField h, ToField i) => ToRecord (a, b, c, d, e, f, g, h, i) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: (a, b, c, d, e, f, g, h, i) -> Record #
(ToField a, ToField b, ToField c, ToField d, ToField e, ToField f, ToField g, ToField h, ToField i, ToField j) => ToRecord (a, b, c, d, e, f, g, h, i, j) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: (a, b, c, d, e, f, g, h, i, j) -> Record #
(ToField a, ToField b, ToField c, ToField d, ToField e, ToField f, ToField g, ToField h, ToField i, ToField j, ToField k) => ToRecord (a, b, c, d, e, f, g, h, i, j, k) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: (a, b, c, d, e, f, g, h, i, j, k) -> Record #
(ToField a, ToField b, ToField c, ToField d, ToField e, ToField f, ToField g, ToField h, ToField i, ToField j, ToField k, ToField l) => ToRecord (a, b, c, d, e, f, g, h, i, j, k, l) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: (a, b, c, d, e, f, g, h, i, j, k, l) -> Record #
(ToField a, ToField b, ToField c, ToField d, ToField e, ToField f, ToField g, ToField h, ToField i, ToField j, ToField k, ToField l, ToField m) => ToRecord (a, b, c, d, e, f, g, h, i, j, k, l, m) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: (a, b, c, d, e, f, g, h, i, j, k, l, m) -> Record #
(ToField a, ToField b, ToField c, ToField d, ToField e, ToField f, ToField g, ToField h, ToField i, ToField j, ToField k, ToField l, ToField m, ToField n) => ToRecord (a, b, c, d, e, f, g, h, i, j, k, l, m, n) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n) -> Record #
(ToField a, ToField b, ToField c, ToField d, ToField e, ToField f, ToField g, ToField h, ToField i, ToField j, ToField k, ToField l, ToField m, ToField n, ToField o) => ToRecord (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) -> Record #

record :: [ByteString] -> Record #

Construct a record from a list of `ByteString`s. Use `toField` to convert values to `ByteString`s for use with `record`.

newtype Only a #

The 1-tuple type or single-value "collection".

This type is structurally equivalent to the `Identity` type, but its intent is more about serving as the anonymous 1-tuple type missing from Haskell for attaching typeclass instances.

Parameter usage example:

    encodeSomething (Only (42::Int))

Result usage example:

    xs <- decodeSomething
    forM_ xs $ \(Only id) -> {- ... -}

Constructors

Only |
Fields fromOnly :: a

#### Instances

Instances details

Functor Only |
Instance details Defined in Data.Tuple.Only Methods fmap :: (a -> b) -> Only a -> Only b # (<$) :: a -> Only b -> Only a #
FromField a => FromRecord (Only a) # |
Instance details Defined in Data.Csv.Conversion Methods parseRecord :: Record -> Parser (Only a) #
ToField a => ToRecord (Only a) # |
Instance details Defined in Data.Csv.Conversion Methods toRecord :: Only a -> Record #
NFData a => NFData (Only a) |
Instance details Defined in Data.Tuple.Only Methods rnf :: Only a -> () #
Data a => Data (Only a) |
Instance details Defined in Data.Tuple.Only Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Only a -> c (Only a) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Only a) # toConstr :: Only a -> Constr # dataTypeOf :: Only a -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Only a)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Only a)) # gmapT :: (forall b. Data b => b -> b) -> Only a -> Only a # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Only a -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Only a -> r # gmapQ :: (forall d. Data d => d -> u) -> Only a -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Only a -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Only a -> m (Only a) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Only a -> m (Only a) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Only a -> m (Only a) #
Generic (Only a) |
Instance details Defined in Data.Tuple.Only Associated Types
type Rep (Only a) |
Instance details Defined in Data.Tuple.Only type Rep (Only a) = D1 ('MetaData "Only" "Data.Tuple.Only" "Only-0.1-1vWhUvIywEwKH1HtIRFVaX" 'True) (C1 ('MetaCons "Only" 'PrefixI 'True) (S1 ('MetaSel ('Just "fromOnly") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)))
Methods from :: Only a -> Rep (Only a) x # to :: Rep (Only a) x -> Only a #
Read a => Read (Only a) |
Instance details Defined in Data.Tuple.Only Methods readsPrec :: Int -> ReadS (Only a) # readList :: ReadS [Only a] # readPrec :: ReadPrec (Only a) # readListPrec :: ReadPrec [Only a] #
Show a => Show (Only a) |
Instance details Defined in Data.Tuple.Only Methods showsPrec :: Int -> Only a -> ShowS # show :: Only a -> String # showList :: [Only a] -> ShowS #
Eq a => Eq (Only a) |
Instance details Defined in Data.Tuple.Only Methods (==) :: Only a -> Only a -> Bool # (/=) :: Only a -> Only a -> Bool #
Ord a => Ord (Only a) |
Instance details Defined in Data.Tuple.Only Methods compare :: Only a -> Only a -> Ordering # (<) :: Only a -> Only a -> Bool # (<=) :: Only a -> Only a -> Bool # (>) :: Only a -> Only a -> Bool # (>=) :: Only a -> Only a -> Bool # max :: Only a -> Only a -> Only a # min :: Only a -> Only a -> Only a #
type Rep (Only a) |
Instance details Defined in Data.Tuple.Only type Rep (Only a) = D1 ('MetaData "Only" "Data.Tuple.Only" "Only-0.1-1vWhUvIywEwKH1HtIRFVaX" 'True) (C1 ('MetaCons "Only" 'PrefixI 'True) (S1 ('MetaSel ('Just "fromOnly") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)))

## Name-based record conversion

Name-based conversion lets you convert CSV records to and from user-defined data types by referring to a field's name. The names of the fields are defined by the first line in the file, also known as the header. Name-based conversion is more robust to changes in the file structure e.g. to reording or addition of columns, but can be a bit slower.

class FromNamedRecord a where #

A type that can be converted from a single CSV record, with the possibility of failure.

When writing an instance, use `empty`, `mzero`, or `fail` to make a conversion fail, e.g. if a `Record` has the wrong number of columns.

Given this example data:

    name,age
    John,56
    Jane,55

here's an example type and instance:

    {-# LANGUAGE OverloadedStrings #-}

    data Person = Person { name :: !Text, age :: !Int }

    instance FromNamedRecord Person where
        parseNamedRecord m = Person <$>
                             m .: "name" <*>
                             m .: "age"

Note the use of the `OverloadedStrings` language extension which enables `ByteString` values to be written as string literals.

Minimal complete definition

Nothing

Methods

parseNamedRecord :: NamedRecord -> Parser a #

default parseNamedRecord :: (Generic a, GFromNamedRecord (Rep a)) => NamedRecord -> Parser a #

#### Instances

Instances details

(FromField a, FromField b, Ord a) => FromNamedRecord (Map a b) # |
Instance details Defined in Data.Csv.Conversion Methods parseNamedRecord :: NamedRecord -> Parser (Map a b) #
(Eq a, FromField a, FromField b, Hashable a) => FromNamedRecord (HashMap a b) # |
Instance details Defined in Data.Csv.Conversion Methods parseNamedRecord :: NamedRecord -> Parser (HashMap a b) #

lookup :: FromField a => NamedRecord -> ByteString -> Parser a #

Retrieve a field in the given record by name. The result is `empty` if the field is missing or if the value cannot be converted to the desired type.

(.:) :: FromField a => NamedRecord -> ByteString -> Parser a #

Alias for `lookup`.

class ToNamedRecord a where #

A type that can be converted to a single CSV record.

An example type and instance:

    data Person = Person { name :: !Text, age :: !Int }

    instance ToNamedRecord Person where
        toNamedRecord (Person name age) = namedRecord [
            "name" .= name, "age" .= age]

Minimal complete definition

Nothing

Methods

toNamedRecord :: a -> NamedRecord #

Convert a value to a named record.

default toNamedRecord :: (Generic a, GToRecord (Rep a) (ByteString, ByteString)) => a -> NamedRecord #

#### Instances

Instances details

(ToField a, ToField b, Ord a) => ToNamedRecord (Map a b) # |
Instance details Defined in Data.Csv.Conversion Methods toNamedRecord :: Map a b -> NamedRecord #
(Eq a, ToField a, ToField b, Hashable a) => ToNamedRecord (HashMap a b) # |
Instance details Defined in Data.Csv.Conversion Methods toNamedRecord :: HashMap a b -> NamedRecord #

namedRecord :: [(ByteString, ByteString)] -> NamedRecord #

Construct a named record from a list of name-value `ByteString` pairs. Use `.=` to construct such a pair from a name and a value.

namedField :: ToField a => ByteString -> a -> (ByteString, ByteString) #

Construct a pair from a name and a value. For use with `namedRecord`.

(.=) :: ToField a => ByteString -> a -> (ByteString, ByteString) #

Alias for `namedField`.

header :: [ByteString] -> Header #

Construct a header from a list of `ByteString`s.

## Field conversion

The `FromField` and `ToField` classes define how to convert between `Field`s and values you care about (e.g. `Int`s). Most of the time you don't need to write your own instances as the standard ones cover most use cases.

class FromField a where #

A type that can be converted from a single CSV field, with the possibility of failure.

When writing an instance, use `empty`, `mzero`, or `fail` to make a conversion fail, e.g. if a `Field` can't be converted to the given type.

Example type and instance:

    {-# LANGUAGE OverloadedStrings #-}

    data Color = Red | Green | Blue

    instance FromField Color where
        parseField s
            | s == "R"  = pure Red
            | s == "G"  = pure Green
            | s == "B"  = pure Blue
            | otherwise = mzero

Methods

parseField :: Field -> Parser a #

#### Instances

Instances details

FromField ByteString # |
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser ByteString #
FromField ByteString # |
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser ByteString #
FromField ShortByteString # |
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser ShortByteString #
FromField Int16 # | Accepts a signed decimal number. Ignores whitespace.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Int16 #
FromField Int32 # | Accepts a signed decimal number. Ignores whitespace.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Int32 #
FromField Int64 # | Accepts a signed decimal number. Ignores whitespace.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Int64 #
FromField Int8 # | Accepts a signed decimal number. Ignores whitespace.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Int8 #
FromField Word16 # | Accepts an unsigned decimal number. Ignores whitespace.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Word16 #
FromField Word32 # | Accepts an unsigned decimal number. Ignores whitespace.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Word32 #
FromField Word64 # | Accepts an unsigned decimal number. Ignores whitespace.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Word64 #
FromField Word8 # | Accepts an unsigned decimal number. Ignores whitespace.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Word8 #
FromField Scientific # | Accepts the same syntax as `rational`. Ignores whitespace. Since: 0.5.1.0
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Scientific #
FromField Text # | Assumes UTF-8 encoding. Fails on invalid byte sequences.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Text #
FromField Text # | Assumes UTF-8 encoding. Fails on invalid byte sequences.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Text #
FromField ShortText # | Assumes UTF-8 encoding. Fails on invalid byte sequences. Since: 0.5.0.0
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser ShortText #
FromField Integer # | Accepts a signed decimal number. Ignores whitespace.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Integer #
FromField Natural # | Accepts an unsigned decimal number. Ignores whitespace. Since: 0.5.1.0
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Natural #
FromField () # | Ignores the `Field`. Always succeeds.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser () #
FromField Char # | Assumes UTF-8 encoding.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Char #
FromField Double # | Accepts same syntax as `rational`. Ignores whitespace.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Double #
FromField Float # | Accepts same syntax as `rational`. Ignores whitespace.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Float #
FromField Int # | Accepts a signed decimal number. Ignores whitespace.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Int #
FromField Word # | Accepts an unsigned decimal number. Ignores whitespace.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser Word #
FromField a => FromField (Identity a) # | Since: 0.5.2.0
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser (Identity a) #
FromField a => FromField (Maybe a) # | `Nothing` if the `Field` is `empty`, `Just` otherwise.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser (Maybe a) #
FromField [Char] # | Assumes UTF-8 encoding. Fails on invalid byte sequences.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser [Char] #
FromField a => FromField (Either Field a) # | ``Left` field` if conversion failed, `Right` otherwise.
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser (Either Field a) #
FromField a => FromField (Const a b) # | Since: 0.5.2.0
Instance details Defined in Data.Csv.Conversion Methods parseField :: Field -> Parser (Const a b) #

class ToField a where #

A type that can be converted to a single CSV field.

Example type and instance:

    {-# LANGUAGE OverloadedStrings #-}

    data Color = Red | Green | Blue

    instance ToField Color where
        toField Red   = "R"
        toField Green = "G"
        toField Blue  = "B"

Methods

toField :: a -> Field #

#### Instances

Instances details

ToField ByteString # |
Instance details Defined in Data.Csv.Conversion Methods toField :: ByteString -> Field #
ToField ByteString # |
Instance details Defined in Data.Csv.Conversion Methods toField :: ByteString -> Field #
ToField ShortByteString # |
Instance details Defined in Data.Csv.Conversion Methods toField :: ShortByteString -> Field #
ToField Int16 # | Uses decimal encoding with optional sign.
Instance details Defined in Data.Csv.Conversion Methods toField :: Int16 -> Field #
ToField Int32 # | Uses decimal encoding with optional sign.
Instance details Defined in Data.Csv.Conversion Methods toField :: Int32 -> Field #
ToField Int64 # | Uses decimal encoding with optional sign.
Instance details Defined in Data.Csv.Conversion Methods toField :: Int64 -> Field #
ToField Int8 # | Uses decimal encoding with optional sign.
Instance details Defined in Data.Csv.Conversion Methods toField :: Int8 -> Field #
ToField Word16 # | Uses decimal encoding.
Instance details Defined in Data.Csv.Conversion Methods toField :: Word16 -> Field #
ToField Word32 # | Uses decimal encoding.
Instance details Defined in Data.Csv.Conversion Methods toField :: Word32 -> Field #
ToField Word64 # | Uses decimal encoding.
Instance details Defined in Data.Csv.Conversion Methods toField :: Word64 -> Field #
ToField Word8 # | Uses decimal encoding.
Instance details Defined in Data.Csv.Conversion Methods toField :: Word8 -> Field #
ToField Scientific # | Uses decimal notation or scientific notation, depending on the number. Since: 0.5.1.0
Instance details Defined in Data.Csv.Conversion Methods toField :: Scientific -> Field #
ToField Text # | Uses UTF-8 encoding.
Instance details Defined in Data.Csv.Conversion Methods toField :: Text -> Field #
ToField Text # | Uses UTF-8 encoding.
Instance details Defined in Data.Csv.Conversion Methods toField :: Text -> Field #
ToField ShortText # | Uses UTF-8 encoding. Since: 0.5.0.0
Instance details Defined in Data.Csv.Conversion Methods toField :: ShortText -> Field #
ToField Integer # | Uses decimal encoding with optional sign.
Instance details Defined in Data.Csv.Conversion Methods toField :: Integer -> Field #
ToField Natural # | Uses decimal encoding. Since: 0.5.1.0
Instance details Defined in Data.Csv.Conversion Methods toField :: Natural -> Field #
ToField Char # | Uses UTF-8 encoding.
Instance details Defined in Data.Csv.Conversion Methods toField :: Char -> Field #
ToField Double # | Uses decimal notation or scientific notation, depending on the number.
Instance details Defined in Data.Csv.Conversion Methods toField :: Double -> Field #
ToField Float # | Uses decimal notation or scientific notation, depending on the number.
Instance details Defined in Data.Csv.Conversion Methods toField :: Float -> Field #
ToField Int # | Uses decimal encoding with optional sign.
Instance details Defined in Data.Csv.Conversion Methods toField :: Int -> Field #
ToField Word # | Uses decimal encoding.
Instance details Defined in Data.Csv.Conversion Methods toField :: Word -> Field #
ToField a => ToField (Identity a) # | Since: 0.5.2.0
Instance details Defined in Data.Csv.Conversion Methods toField :: Identity a -> Field #
ToField a => ToField (Maybe a) # | `Nothing` is encoded as an `empty` field.
Instance details Defined in Data.Csv.Conversion Methods toField :: Maybe a -> Field #
ToField [Char] # | Uses UTF-8 encoding.
Instance details Defined in Data.Csv.Conversion Methods toField :: [Char] -> Field #
ToField a => ToField (Const a b) # | Since: 0.5.2.0
Instance details Defined in Data.Csv.Conversion Methods toField :: Const a b -> Field #

## `Generic` record conversion

There may be times that you do not want to manually write out class instances for record conversion, but you can't rely upon the default instances (e.g. you can't create field names that match the actual column names in expected data).

For example, consider you have a type `MyType` where you have prefixed certain columns with an underscore, but in the actual data they're not. You can then write:

    myOptions :: Options
    myOptions = defaultOptions { fieldLabelModifier = rmUnderscore }
      where
        rmUnderscore ('_':str) = str
        rmUnderscore str       = str

    instance ToNamedRecord MyType where
      toNamedRecord = genericToNamedRecord myOptions

    instance FromNamedRecord MyType where
      parseNamedRecord = genericParseNamedRecord myOptions

    instance DefaultOrdered MyType where
      headerOrder = genericHeaderOrder myOptions

genericParseRecord :: (Generic a, GFromRecord (Rep a)) => Options -> Record -> Parser a #

A configurable CSV record parser. This function applied to `defaultOptions` is used as the default for `parseRecord` when the type is an instance of `Generic`.

Since: 0.5.1.0

genericToRecord :: (Generic a, GToRecord (Rep a) Field) => Options -> a -> Record #

A configurable CSV record creator. This function applied to `defaultOptions` is used as the default for `toRecord` when the type is an instance of `Generic`.

Since: 0.5.1.0

genericParseNamedRecord :: (Generic a, GFromNamedRecord (Rep a)) => Options -> NamedRecord -> Parser a #

A configurable CSV named record parser. This function applied to `defaultOptions` is used as the default for `parseNamedRecord` when the type is an instance of `Generic`.

Since: 0.5.1.0

genericToNamedRecord :: (Generic a, GToRecord (Rep a) (ByteString, ByteString)) => Options -> a -> NamedRecord #

A configurable CSV named record creator. This function applied to `defaultOptions` is used as the default for `toNamedRecord` when the type is an instance of `Generic`.

Since: 0.5.1.0

genericHeaderOrder :: (Generic a, GToNamedRecordHeader (Rep a)) => Options -> a -> Header #

A configurable CSV header record generator. This function applied to `defaultOptions` is used as the default for `headerOrder` when the type is an instance of `Generic`.

Since: 0.5.1.0

### `Generic` type conversion options

data Options #

Options to customise how to generically encode/decode your datatype to/from CSV.

Since: 0.5.1.0

#### Instances

Instances details

Show Options # |
Instance details Defined in Data.Csv.Conversion Methods showsPrec :: Int -> Options -> ShowS # show :: Options -> String # showList :: [Options] -> ShowS #

defaultOptions :: Options #

Default conversion options.

      Options
      { fieldLabelModifier = id
      }

Since: 0.5.1.0

fieldLabelModifier :: Options -> String -> String #

How to convert Haskell field labels to CSV fields.

Since: 0.5.1.0

### `Generic` type conversion class name

NOTE: Only the class names are exposed in order to make it possible to write type signatures referring to these classes

class GFromRecord (f :: k -> Type) #

Minimal complete definition

gparseRecord

#### Instances

Instances details

GFromRecordSum f Record => GFromRecord (M1 i n f :: k -> Type) # |
Instance details Defined in Data.Csv.Conversion Methods gparseRecord :: forall (p :: k). Options -> Record -> Parser (M1 i n f p)

class GToRecord (a :: k -> Type) f #

Minimal complete definition

gtoRecord

#### Instances

Instances details

GToRecord (U1 :: k -> Type) f # |
Instance details Defined in Data.Csv.Conversion Methods gtoRecord :: forall (p :: k). Options -> U1 p -> [f]
(GToRecord a f, GToRecord b f) => GToRecord (a :*: b :: k -> Type) f # |
Instance details Defined in Data.Csv.Conversion Methods gtoRecord :: forall (p :: k). Options -> (a :*: b) p -> [f]
(GToRecord a f, GToRecord b f) => GToRecord (a :+: b :: k -> Type) f # |
Instance details Defined in Data.Csv.Conversion Methods gtoRecord :: forall (p :: k). Options -> (a :+: b) p -> [f]
ToField a => GToRecord (K1 i a :: k -> Type) Field # |
Instance details Defined in Data.Csv.Conversion Methods gtoRecord :: forall (p :: k). Options -> K1 i a p -> [Field]
GToRecord a f => GToRecord (M1 C c a :: k -> Type) f # |
Instance details Defined in Data.Csv.Conversion Methods gtoRecord :: forall (p :: k). Options -> M1 C c a p -> [f]
GToRecord a f => GToRecord (M1 D c a :: k -> Type) f # |
Instance details Defined in Data.Csv.Conversion Methods gtoRecord :: forall (p :: k). Options -> M1 D c a p -> [f]
GToRecord a Field => GToRecord (M1 S c a :: k -> Type) Field # |
Instance details Defined in Data.Csv.Conversion Methods gtoRecord :: forall (p :: k). Options -> M1 S c a p -> [Field]
(ToField a, Selector s) => GToRecord (M1 S s (K1 i a :: k -> Type) :: k -> Type) (ByteString, ByteString) # |
Instance details Defined in Data.Csv.Conversion Methods gtoRecord :: forall (p :: k). Options -> M1 S s (K1 i a :: k -> Type) p -> [(ByteString, ByteString)]

class GFromNamedRecord (f :: k -> Type) #

Minimal complete definition

gparseNamedRecord

#### Instances

Instances details

GFromRecordSum f NamedRecord => GFromNamedRecord (M1 i n f :: k -> Type) # |
Instance details Defined in Data.Csv.Conversion Methods gparseNamedRecord :: forall (p :: k). Options -> NamedRecord -> Parser (M1 i n f p)

class GToNamedRecordHeader (a :: k -> Type) #

Minimal complete definition

gtoNamedRecordHeader

#### Instances

Instances details

GToNamedRecordHeader (U1 :: k -> Type) # |
Instance details Defined in Data.Csv.Conversion Methods gtoNamedRecordHeader :: forall (p :: k). Options -> U1 p -> [Name]
(GToNamedRecordHeader a, GToNamedRecordHeader b) => GToNamedRecordHeader (a :*: b :: k -> Type) # |
Instance details Defined in Data.Csv.Conversion Methods gtoNamedRecordHeader :: forall (p :: k). Options -> (a :*: b) p -> [Name]
DefaultOrdered (M1 S ('MetaSel ('Nothing :: Maybe Symbol) srcpk srcstr decstr) a ()) => GToNamedRecordHeader (M1 S ('MetaSel ('Nothing :: Maybe Symbol) srcpk srcstr decstr) a :: Type -> Type) # | Instance to ensure that you cannot derive DefaultOrdered for constructors without selectors.
Instance details Defined in Data.Csv.Conversion Methods gtoNamedRecordHeader :: Options -> M1 S ('MetaSel ('Nothing :: Maybe Symbol) srcpk srcstr decstr) a p -> [Name]
GToNamedRecordHeader a => GToNamedRecordHeader (M1 C c a :: k -> Type) # |
Instance details Defined in Data.Csv.Conversion Methods gtoNamedRecordHeader :: forall (p :: k). Options -> M1 C c a p -> [Name]
GToNamedRecordHeader a => GToNamedRecordHeader (M1 D c a :: k -> Type) # |
Instance details Defined in Data.Csv.Conversion Methods gtoNamedRecordHeader :: forall (p :: k). Options -> M1 D c a p -> [Name]
Selector s => GToNamedRecordHeader (M1 S s a :: k -> Type) # |
Instance details Defined in Data.Csv.Conversion Methods gtoNamedRecordHeader :: forall (p :: k). Options -> M1 S s a p -> [Name]