Csv represents a CSV table as an optional header plus a list of columns. Each column contains DataField values, allowing text, integers, and nulls to appear in the same table or column. section 7.1.2
Listing 7.3 A data type for CSV tables
type Column = [DataField] #1
data Csv = Csv
{ csvHeader :: Maybe [T.Text], #2
csvColumns :: [Column] #3
}
deriving (Show)
The record keeps the optional header separate from column-oriented table data. section 7.1.2
A Csv value has two construction invariants: a present header must contain one name per column, and every column must have the same number of cells. Construct tables with mkCsv to receive either an explanatory error or a valid Csv. section 7.2.1
Safe and unsafe construction
mkCsv returns Right for a rectangular table with a matching header, and Left when column lengths or header size disagree. unsafeMkCsv converts that result into a Csv or crashes; reserve it for inputs already known to be valid. section 7.2.2
Once constructed, Csv supports table-oriented operations:
- Count rows from the first column and columns from the column list. section 7.3
- Slice headers and columns together through a Sliceable Csv instance, producing three Csv pieces. section 7.4.1
- Parse text into validated columns, transpose rows into columns, and return parsing failures through Either. section 8.2.4
Parsing can use default options with or without a header. Parsed fields are converted to DataField values, so the resulting Csv is ready for later searching, sums, transformations, and printing. section 8.0 section 8.2.4
