{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
module RTable.Data.CSV
(
CSV (..)
,Row
,Column
,CSVOptions(..)
,YesNo (..)
,readCSV
,readCSVwithOptions
,readCSVFile
,writeCSV
,writeCSVFile
,toRTable
,fromRTable
,printCSV
,printCSVFile
,copyCSV
,selectNrows
,projectByIndex
,headCSV
,tailCSV
,csvHeaderFromRtable
,CsvFileDecodingError (..)
,CSVColumnToRDataTypeError (..)
) where
import Debug.Trace
import RTable.Core
import qualified Data.Csv as CV
import qualified Data.HashMap.Strict as HM
import Data.List (map)
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString as BS
import Data.ByteString.Char8 (pack,unpack)
import Prelude hiding (putStr)
import Data.ByteString.Lazy.Char8 (putStr)
import Data.Text as T
import Data.Text.Encoding (decodeUtf8, encodeUtf8, decodeUtf8', decodeUtf16LE)
import qualified Data.Vector as V
import Data.Maybe (fromJust)
import Data.Serialize (decode, encode)
import qualified Data.Typeable as TB
import Data.Either.Combinators (fromRight')
import Data.Char (ord)
import Text.Printf (printf)
import Control.Exception
newtype CSV = CSV {CSV -> Vector Row
csv :: V.Vector Row}
instance RTabular CSV where
toRTable :: RTableMData -> CSV -> RTable
toRTable = RTableMData -> CSV -> RTable
csvToRTable
fromRTable :: RTableMData -> RTable -> CSV
fromRTable = RTableMData -> RTable -> CSV
rtableToCSV
type Row = V.Vector Column
type Column = CV.Field
readCSVFile ::
FilePath
-> IO BL.ByteString
readCSVFile :: FilePath -> IO ByteString
readCSVFile FilePath
f = FilePath -> IO ByteString
BL.readFile FilePath
f
readCSV ::
FilePath
-> IO CSV
readCSV :: FilePath -> IO CSV
readCSV FilePath
f = do
ByteString
csvData <- FilePath -> IO ByteString
BL.readFile FilePath
f
let
csvResult :: Vector a
csvResult =
case HasHeader -> ByteString -> Either FilePath (Vector a)
forall a.
FromRecord a =>
HasHeader -> ByteString -> Either FilePath (Vector a)
CV.decode HasHeader
CV.HasHeader ByteString
csvData of
Left FilePath
str -> CsvFileDecodingError -> Vector a
forall a e. Exception e => e -> a
throw (CsvFileDecodingError -> Vector a)
-> CsvFileDecodingError -> Vector a
forall a b. (a -> b) -> a -> b
$ FilePath -> Text -> CsvFileDecodingError
CsvFileDecodingError FilePath
f (Text -> CsvFileDecodingError) -> Text -> CsvFileDecodingError
forall a b. (a -> b) -> a -> b
$ FilePath -> Text
T.pack FilePath
str
Right Vector a
res -> Vector a
res
CSV -> IO CSV
forall (m :: * -> *) a. Monad m => a -> m a
return (CSV -> IO CSV) -> CSV -> IO CSV
forall a b. (a -> b) -> a -> b
$ Vector Row -> CSV
CSV Vector Row
forall a. FromRecord a => Vector a
csvResult
data YesNo = Yes | No
data CSVOptions = CSVOptions {
CSVOptions -> Char
delimiter :: Char
, :: YesNo
}
readCSVwithOptions ::
CSVOptions
-> FilePath
-> IO CSV
readCSVwithOptions :: CSVOptions -> FilePath -> IO CSV
readCSVwithOptions CSVOptions
opt FilePath
f = do
ByteString
csvData <- FilePath -> IO ByteString
BL.readFile FilePath
f
let csvoptions :: DecodeOptions
csvoptions = DecodeOptions
CV.defaultDecodeOptions {
decDelimiter :: Word8
CV.decDelimiter = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Char -> Int
ord (CSVOptions -> Char
delimiter CSVOptions
opt)
}
csvResult :: Vector a
csvResult = case DecodeOptions
-> HasHeader -> ByteString -> Either FilePath (Vector a)
forall a.
FromRecord a =>
DecodeOptions
-> HasHeader -> ByteString -> Either FilePath (Vector a)
CV.decodeWith DecodeOptions
csvoptions
(case (CSVOptions -> YesNo
hasHeader CSVOptions
opt) of
YesNo
Yes -> HasHeader
CV.HasHeader
YesNo
No -> HasHeader
CV.NoHeader)
ByteString
csvData of
Left FilePath
str -> CsvFileDecodingError -> Vector a
forall a e. Exception e => e -> a
throw (CsvFileDecodingError -> Vector a)
-> CsvFileDecodingError -> Vector a
forall a b. (a -> b) -> a -> b
$ FilePath -> Text -> CsvFileDecodingError
CsvFileDecodingError FilePath
f (Text -> CsvFileDecodingError) -> Text -> CsvFileDecodingError
forall a b. (a -> b) -> a -> b
$ FilePath -> Text
T.pack FilePath
str
Right Vector a
res -> Vector a
res
CSV -> IO CSV
forall (m :: * -> *) a. Monad m => a -> m a
return (CSV -> IO CSV) -> CSV -> IO CSV
forall a b. (a -> b) -> a -> b
$ Vector Row -> CSV
CSV Vector Row
forall a. FromRecord a => Vector a
csvResult
writeCSVFile ::
FilePath
-> BL.ByteString
-> IO()
writeCSVFile :: FilePath -> ByteString -> IO ()
writeCSVFile FilePath
f ByteString
csv = FilePath -> ByteString -> IO ()
BL.writeFile FilePath
f ByteString
csv
writeCSV ::
FilePath
-> CSV
-> IO()
writeCSV :: FilePath -> CSV -> IO ()
writeCSV FilePath
f (CSV Vector Row
csv) = do
let csvBS :: ByteString
csvBS = [Row] -> ByteString
forall a. ToRecord a => [a] -> ByteString
CV.encode (Vector Row -> [Row]
forall a. Vector a -> [a]
V.toList Vector Row
csv)
FilePath -> ByteString -> IO ()
BL.writeFile FilePath
f ByteString
csvBS
printCSVFile ::
BL.ByteString
-> IO()
printCSVFile :: ByteString -> IO ()
printCSVFile ByteString
csv = ByteString -> IO ()
putStr ByteString
csv
printCSV ::
CSV
-> IO()
printCSV :: CSV -> IO ()
printCSV (CSV Vector Row
csv) = do
let csvBS :: ByteString
csvBS = [Row] -> ByteString
forall a. ToRecord a => [a] -> ByteString
CV.encode (Vector Row -> [Row]
forall a. Vector a -> [a]
V.toList Vector Row
csv)
ByteString -> IO ()
putStr ByteString
csvBS
copyCSV ::
FilePath
->FilePath
-> IO()
copyCSV :: FilePath -> FilePath -> IO ()
copyCSV FilePath
fi FilePath
fo = do
CSV
csv <- FilePath -> IO CSV
readCSV FilePath
fi
FilePath -> CSV -> IO ()
writeCSV FilePath
fo CSV
csv
csvToRTable ::
RTableMData
-> CSV
-> RTable
csvToRTable :: RTableMData -> CSV -> RTable
csvToRTable RTableMData
m (CSV Vector Row
c) =
(Row -> RTuple) -> Vector Row -> RTable
forall a b. (a -> b) -> Vector a -> Vector b
V.map (RTableMData -> Row -> RTuple
row2RTuple RTableMData
m) Vector Row
c
where
row2RTuple :: RTableMData -> Row -> RTuple
row2RTuple :: RTableMData -> Row -> RTuple
row2RTuple RTableMData
md Row
row =
let
listOfColInfo :: [ColumnInfo]
listOfColInfo = RTupleMData -> [ColumnInfo]
toListColumnInfo (RTableMData -> RTupleMData
rtuplemdata RTableMData
md)
listOfColInfoColumn :: [(ColumnInfo, Column)]
listOfColInfoColumn = [ColumnInfo] -> [Column] -> [(ColumnInfo, Column)]
forall a b. [a] -> [b] -> [(a, b)]
Prelude.zip [ColumnInfo]
listOfColInfo (Row -> [Column]
forall a. Vector a -> [a]
V.toList Row
row)
listOfColNames :: [Text]
listOfColNames = RTupleMData -> [Text]
toListColumnName (RTableMData -> RTupleMData
rtuplemdata RTableMData
md)
listOfRDataTypes :: [RDataType]
listOfRDataTypes = ((ColumnInfo, Column) -> RDataType)
-> [(ColumnInfo, Column)] -> [RDataType]
forall a b. (a -> b) -> [a] -> [b]
Prelude.map (\(ColumnInfo
ci,Column
co) -> ColumnInfo -> Column -> RDataType
column2RDataType ColumnInfo
ci Column
co) ([(ColumnInfo, Column)] -> [RDataType])
-> [(ColumnInfo, Column)] -> [RDataType]
forall a b. (a -> b) -> a -> b
$ [(ColumnInfo, Column)]
listOfColInfoColumn
where
column2RDataType :: ColumnInfo -> Column -> RDataType
column2RDataType :: ColumnInfo -> Column -> RDataType
column2RDataType ColumnInfo
ci Column
col =
if Column
col Column -> Column -> Bool
forall a. Eq a => a -> a -> Bool
== Column
BS.empty
then
RDataType
Null
else
case (ColumnInfo -> ColumnDType
dtype ColumnInfo
ci) of
ColumnDType
Integer -> Integer -> RDataType
RInt (Integer
forall p. FromField p => p
val::Integer)
ColumnDType
Varchar -> Text -> RDataType
RText (Text -> RDataType) -> Text -> RDataType
forall a b. (a -> b) -> a -> b
$ if Bool
False then FilePath -> Text -> Text
forall a. FilePath -> a -> a
trace (FilePath
"Creating RText for column " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ (Text -> FilePath
T.unpack (Text -> FilePath) -> Text -> FilePath
forall a b. (a -> b) -> a -> b
$ ColumnInfo -> Text
name ColumnInfo
ci)) (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ (Text
forall p. FromField p => p
val::T.Text) else (Text
forall p. FromField p => p
val::T.Text)
Date Text
fmt -> RDate :: Text -> Text -> RDataType
RDate { rdate :: Text
rdate = (Text
forall p. FromField p => p
val::T.Text) , dtformat :: Text
dtformat = Text
fmt }
Timestamp Text
fmt -> RTimestamp -> RDataType
RTime (RTimestamp -> RDataType) -> RTimestamp -> RDataType
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath -> RTimestamp
createRTimestamp (Text -> FilePath
T.unpack Text
fmt) (Column -> FilePath
Data.ByteString.Char8.unpack Column
col)
ColumnDType
Double -> Double -> RDataType
RDouble (Double
forall p. FromField p => p
val::Double)
where
val :: p
val = case Parser p -> Either FilePath p
forall a. Parser a -> Either FilePath a
CV.runParser (Parser p -> Either FilePath p) -> Parser p -> Either FilePath p
forall a b. (a -> b) -> a -> b
$ Column -> Parser p
forall a. FromField a => Column -> Parser a
CV.parseField Column
col of
Left FilePath
str -> CSVColumnToRDataTypeError -> p
forall a e. Exception e => e -> a
throw (CSVColumnToRDataTypeError -> p) -> CSVColumnToRDataTypeError -> p
forall a b. (a -> b) -> a -> b
$ Text -> Text -> CSVColumnToRDataTypeError
CSVColumnToRDataTypeError (ColumnInfo -> Text
name ColumnInfo
ci) (Text -> CSVColumnToRDataTypeError)
-> Text -> CSVColumnToRDataTypeError
forall a b. (a -> b) -> a -> b
$ FilePath -> Text
T.pack FilePath
str
Right p
v -> p
v
in [(Text, RDataType)] -> RTuple
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HM.fromList ([(Text, RDataType)] -> RTuple) -> [(Text, RDataType)] -> RTuple
forall a b. (a -> b) -> a -> b
$ [Text] -> [RDataType] -> [(Text, RDataType)]
forall a b. [a] -> [b] -> [(a, b)]
Prelude.zip [Text]
listOfColNames [RDataType]
listOfRDataTypes
rtableToCSV ::
RTableMData
-> RTable
-> CSV
rtableToCSV :: RTableMData -> RTable -> CSV
rtableToCSV RTableMData
m RTable
t =
Vector Row -> CSV
CSV (Vector Row -> CSV) -> Vector Row -> CSV
forall a b. (a -> b) -> a -> b
$ (CSV -> Vector Row
csv (CSV -> Vector Row) -> CSV -> Vector Row
forall a b. (a -> b) -> a -> b
$ RTableMData -> CSV
createCSVHeader RTableMData
m) Vector Row -> Vector Row -> Vector Row
forall a. Vector a -> Vector a -> Vector a
V.++ ((RTuple -> Row) -> RTable -> Vector Row
forall a b. (a -> b) -> Vector a -> Vector b
V.map (RTableMData -> RTuple -> Row
rtuple2row RTableMData
m) RTable
t)
where
rtuple2row :: RTableMData -> RTuple -> Row
rtuple2row :: RTableMData -> RTuple -> Row
rtuple2row RTableMData
md RTuple
rt =
if Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ RTuple -> Bool
isRTupEmpty RTuple
rt
then
let listOfColInfo :: [ColumnInfo]
listOfColInfo = RTupleMData -> [ColumnInfo]
toListColumnInfo (RTableMData -> RTupleMData
rtuplemdata RTableMData
md)
listOfColInfoRDataType :: [ColumnInfo] -> RTuple -> [(ColumnInfo, RDataType)]
listOfColInfoRDataType :: [ColumnInfo] -> RTuple -> [(ColumnInfo, RDataType)]
listOfColInfoRDataType (ColumnInfo
ci:[]) RTuple
rtup = [(ColumnInfo
ci, RTuple
rtup RTuple -> Text -> RDataType
forall k v.
(Eq k, Hashable k, HasCallStack) =>
HashMap k v -> k -> v
HM.!(ColumnInfo -> Text
name ColumnInfo
ci))]
listOfColInfoRDataType (ColumnInfo
ci:[ColumnInfo]
colInfos) RTuple
rtup = (ColumnInfo
ci, RTuple
rtup RTuple -> Text -> RDataType
forall k v.
(Eq k, Hashable k, HasCallStack) =>
HashMap k v -> k -> v
HM.!(ColumnInfo -> Text
name ColumnInfo
ci))(ColumnInfo, RDataType)
-> [(ColumnInfo, RDataType)] -> [(ColumnInfo, RDataType)]
forall a. a -> [a] -> [a]
:[ColumnInfo] -> RTuple -> [(ColumnInfo, RDataType)]
listOfColInfoRDataType [ColumnInfo]
colInfos RTuple
rtup
listOfColumns :: [Column]
listOfColumns = ((ColumnInfo, RDataType) -> Column)
-> [(ColumnInfo, RDataType)] -> [Column]
forall a b. (a -> b) -> [a] -> [b]
Prelude.map (\(ColumnInfo
ci,RDataType
rdt) -> ColumnInfo -> RDataType -> Column
rDataType2Column ColumnInfo
ci RDataType
rdt) ([(ColumnInfo, RDataType)] -> [Column])
-> [(ColumnInfo, RDataType)] -> [Column]
forall a b. (a -> b) -> a -> b
$ [ColumnInfo] -> RTuple -> [(ColumnInfo, RDataType)]
listOfColInfoRDataType [ColumnInfo]
listOfColInfo RTuple
rt
where
rDataType2Column :: ColumnInfo -> RDataType -> Column
rDataType2Column :: ColumnInfo -> RDataType -> Column
rDataType2Column ColumnInfo
_ RDataType
rdt =
case RDataType
rdt of
RInt Integer
i -> Integer -> Column
forall a. ToField a => a -> Column
CV.toField Integer
i
RText Text
t -> Text -> Column
forall a. ToField a => a -> Column
CV.toField Text
t
RDate {rdate :: RDataType -> Text
rdate = Text
d, dtformat :: RDataType -> Text
dtformat = Text
f} -> Text -> Column
forall a. ToField a => a -> Column
CV.toField Text
d
RDouble Double
db -> FilePath -> Column
forall a. ToField a => a -> Column
CV.toField ((FilePath -> Double -> FilePath
forall r. PrintfType r => FilePath -> r
printf FilePath
"%.2f" Double
db)::String)
RTime { rtime :: RDataType -> RTimestamp
rtime = RTimestampVal {year :: RTimestamp -> Int
year = Int
y, month :: RTimestamp -> Int
month = Int
m, day :: RTimestamp -> Int
day = Int
d, hours24 :: RTimestamp -> Int
hours24 = Int
h, minutes :: RTimestamp -> Int
minutes = Int
mi, seconds :: RTimestamp -> Int
seconds = Int
s} } -> let timeText :: Text
timeText = (Int -> Text
digitToText Int
d) Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend` FilePath -> Text
T.pack FilePath
"/" Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend` (Int -> Text
digitToText Int
m) Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend` FilePath -> Text
T.pack FilePath
"/" Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend` (Int -> Text
digitToText Int
y) Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend` FilePath -> Text
T.pack FilePath
" " Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend` (Int -> Text
digitToText Int
h) Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend` FilePath -> Text
T.pack FilePath
":" Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend` (Int -> Text
digitToText Int
mi) Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend` FilePath -> Text
T.pack FilePath
":" Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend` (Int -> Text
digitToText Int
s)
where digitToText :: Int -> T.Text
digitToText :: Int -> Text
digitToText Int
d =
if Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
9 then Int -> Text
forall a. Show a => a -> Text
showText Int
d
else Text
"0" Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend` (Int -> Text
forall a. Show a => a -> Text
showText Int
d)
showText :: Show a => a -> Text
showText :: a -> Text
showText = FilePath -> Text
T.pack (FilePath -> Text) -> (a -> FilePath) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> FilePath
forall a. Show a => a -> FilePath
show
in Text -> Column
forall a. ToField a => a -> Column
CV.toField Text
timeText
RDataType
Null -> Text -> Column
forall a. ToField a => a -> Column
CV.toField (Text
""::T.Text)
in [Column] -> Row
forall a. [a] -> Vector a
V.fromList ([Column] -> Row) -> [Column] -> Row
forall a b. (a -> b) -> a -> b
$ [Column]
listOfColumns
else Row
forall a. Vector a
V.empty::Row
createCSVHeader :: RTableMData -> CSV
createCSVHeader :: RTableMData -> CSV
createCSVHeader RTableMData
md =
let listOfColNames :: [Text]
listOfColNames = RTupleMData -> [Text]
toListColumnName (RTableMData -> RTupleMData
rtuplemdata RTableMData
md)
listOfByteStrings :: [Column]
listOfByteStrings = (Text -> Column) -> [Text] -> [Column]
forall a b. (a -> b) -> [a] -> [b]
Prelude.map (\Text
n -> Text -> Column
forall a. ToField a => a -> Column
CV.toField Text
n) [Text]
listOfColNames
headerRow :: Row
headerRow = [Column] -> Row
forall a. [a] -> Vector a
V.fromList [Column]
listOfByteStrings
in Vector Row -> CSV
CSV (Vector Row -> CSV) -> Vector Row -> CSV
forall a b. (a -> b) -> a -> b
$ Row -> Vector Row
forall a. a -> Vector a
V.singleton Row
headerRow
csvHeaderFromRtable ::
RTable
-> CV.Header
RTable
rtab =
let fstRTuple :: RTuple
fstRTuple = RTable -> RTuple
forall a. Vector a -> a
V.head RTable
rtab
colList :: [Text]
colList = RTuple -> [Text]
forall k v. HashMap k v -> [k]
HM.keys RTuple
fstRTuple
colListPacked :: [Column]
colListPacked = (Text -> Column) -> [Text] -> [Column]
forall a b. (a -> b) -> [a] -> [b]
Prelude.map (FilePath -> Column
forall a. Serialize a => a -> Column
encode (FilePath -> Column) -> (Text -> FilePath) -> Text -> Column
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> FilePath
T.unpack) [Text]
colList
header :: Row
header = [Column] -> Row
forall a. [a] -> Vector a
V.fromList [Column]
colListPacked
in Row
header
headCSV :: CSV -> Row
headCSV :: CSV -> Row
headCSV = Vector Row -> Row
forall a. Vector a -> a
V.head (Vector Row -> Row) -> (CSV -> Vector Row) -> CSV -> Row
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CSV -> Vector Row
csv
tailCSV :: CSV -> CSV
tailCSV :: CSV -> CSV
tailCSV = Vector Row -> CSV
CSV (Vector Row -> CSV) -> (CSV -> Vector Row) -> CSV -> CSV
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector Row -> Vector Row
forall a. Vector a -> Vector a
V.tail (Vector Row -> Vector Row)
-> (CSV -> Vector Row) -> CSV -> Vector Row
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CSV -> Vector Row
csv
selectNrows ::
Int
-> CSV
-> CSV
selectNrows :: Int -> CSV -> CSV
selectNrows Int
n CSV
icsv = Vector Row -> CSV
CSV (Vector Row -> CSV) -> Vector Row -> CSV
forall a b. (a -> b) -> a -> b
$ Int -> Vector Row -> Vector Row
forall a. Int -> Vector a -> Vector a
V.take Int
n (CSV -> Vector Row
csv CSV
icsv)
projectByIndex ::
[Int]
-> CSV
-> CSV
projectByIndex :: [Int] -> CSV -> CSV
projectByIndex [Int]
inds (CSV Vector Row
icsv) =
(Row -> CSV -> CSV) -> CSV -> Vector Row -> CSV
forall a b. (a -> b -> b) -> b -> Vector a -> b
V.foldr (Row -> CSV -> CSV
prj) (Vector Row -> CSV
CSV (Vector Row -> CSV) -> Vector Row -> CSV
forall a b. (a -> b) -> a -> b
$ Vector Row
forall a. Vector a
V.empty) Vector Row
icsv
where
prj :: Row -> CSV -> CSV
prj :: Row -> CSV -> CSV
prj Row
row (CSV Vector Row
acc) =
let
newrow :: Row
newrow = [Column] -> Row
forall a. [a] -> Vector a
V.fromList ([Column] -> Row) -> [Column] -> Row
forall a b. (a -> b) -> a -> b
$ (Int -> Column) -> [Int] -> [Column]
forall a b. (a -> b) -> [a] -> [b]
Data.List.map (\Int
i -> Row
row Row -> Int -> Column
forall a. Vector a -> Int -> a
V.! Int
i) [Int]
inds
in
Vector Row -> CSV
CSV (Vector Row -> CSV) -> Vector Row -> CSV
forall a b. (a -> b) -> a -> b
$ Vector Row -> Row -> Vector Row
forall a. Vector a -> a -> Vector a
V.snoc Vector Row
acc Row
newrow
data CsvFileDecodingError = CsvFileDecodingError FilePath Text deriving(CsvFileDecodingError -> CsvFileDecodingError -> Bool
(CsvFileDecodingError -> CsvFileDecodingError -> Bool)
-> (CsvFileDecodingError -> CsvFileDecodingError -> Bool)
-> Eq CsvFileDecodingError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CsvFileDecodingError -> CsvFileDecodingError -> Bool
$c/= :: CsvFileDecodingError -> CsvFileDecodingError -> Bool
== :: CsvFileDecodingError -> CsvFileDecodingError -> Bool
$c== :: CsvFileDecodingError -> CsvFileDecodingError -> Bool
Eq,Int -> CsvFileDecodingError -> FilePath -> FilePath
[CsvFileDecodingError] -> FilePath -> FilePath
CsvFileDecodingError -> FilePath
(Int -> CsvFileDecodingError -> FilePath -> FilePath)
-> (CsvFileDecodingError -> FilePath)
-> ([CsvFileDecodingError] -> FilePath -> FilePath)
-> Show CsvFileDecodingError
forall a.
(Int -> a -> FilePath -> FilePath)
-> (a -> FilePath) -> ([a] -> FilePath -> FilePath) -> Show a
showList :: [CsvFileDecodingError] -> FilePath -> FilePath
$cshowList :: [CsvFileDecodingError] -> FilePath -> FilePath
show :: CsvFileDecodingError -> FilePath
$cshow :: CsvFileDecodingError -> FilePath
showsPrec :: Int -> CsvFileDecodingError -> FilePath -> FilePath
$cshowsPrec :: Int -> CsvFileDecodingError -> FilePath -> FilePath
Show)
instance Exception CsvFileDecodingError
data CSVColumnToRDataTypeError = CSVColumnToRDataTypeError ColumnName Text deriving(CSVColumnToRDataTypeError -> CSVColumnToRDataTypeError -> Bool
(CSVColumnToRDataTypeError -> CSVColumnToRDataTypeError -> Bool)
-> (CSVColumnToRDataTypeError -> CSVColumnToRDataTypeError -> Bool)
-> Eq CSVColumnToRDataTypeError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CSVColumnToRDataTypeError -> CSVColumnToRDataTypeError -> Bool
$c/= :: CSVColumnToRDataTypeError -> CSVColumnToRDataTypeError -> Bool
== :: CSVColumnToRDataTypeError -> CSVColumnToRDataTypeError -> Bool
$c== :: CSVColumnToRDataTypeError -> CSVColumnToRDataTypeError -> Bool
Eq,Int -> CSVColumnToRDataTypeError -> FilePath -> FilePath
[CSVColumnToRDataTypeError] -> FilePath -> FilePath
CSVColumnToRDataTypeError -> FilePath
(Int -> CSVColumnToRDataTypeError -> FilePath -> FilePath)
-> (CSVColumnToRDataTypeError -> FilePath)
-> ([CSVColumnToRDataTypeError] -> FilePath -> FilePath)
-> Show CSVColumnToRDataTypeError
forall a.
(Int -> a -> FilePath -> FilePath)
-> (a -> FilePath) -> ([a] -> FilePath -> FilePath) -> Show a
showList :: [CSVColumnToRDataTypeError] -> FilePath -> FilePath
$cshowList :: [CSVColumnToRDataTypeError] -> FilePath -> FilePath
show :: CSVColumnToRDataTypeError -> FilePath
$cshow :: CSVColumnToRDataTypeError -> FilePath
showsPrec :: Int -> CSVColumnToRDataTypeError -> FilePath -> FilePath
$cshowsPrec :: Int -> CSVColumnToRDataTypeError -> FilePath -> FilePath
Show)
instance Exception CSVColumnToRDataTypeError