Frames 0.1.6 → 0.1.8
raw patch · 4 files changed
+38/−21 lines, 4 filesdep ~Chartdep ~Chart-diagramsdep ~pipesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: Chart, Chart-diagrams, pipes
API changes (from Hackage documentation)
- Frames.CSV: recDec :: ColumnTypeable a => [(Text, a)] -> Q Type
+ Frames.CSV: recDec :: [(Text, Q Type)] -> Q Type
Files
- Frames.cabal +11/−11
- src/Frames/CSV.hs +15/−10
- src/Frames/ColumnTypeable.hs +2/−0
- src/Frames/ColumnUniverse.hs +10/−0
Frames.cabal view
@@ -1,5 +1,5 @@ name: Frames-version: 0.1.6+version: 0.1.8 synopsis: Data frames For working with tabular data files description: User-friendly, type safe, runtime efficient tooling for working with tabular data deserialized from@@ -82,9 +82,9 @@ build-depends: base, Frames, microlens, vector, text, template-haskell,- pipes >= 4.1.5 && < 4.3,- Chart >= 1.5 && < 1.8,- Chart-diagrams >= 1.5 && < 1.8,+ pipes >= 4.1.5 && < 4.4,+ Chart >= 1.5 && < 1.9,+ Chart-diagrams >= 1.5 && < 1.9, diagrams-rasterific >= 1.3 && < 1.4, diagrams-lib >= 1.3 && < 1.4, readable, containers, statistics@@ -98,9 +98,9 @@ if flag(demos) build-depends: base, Frames, microlens, vector, text, template-haskell,- pipes >= 4.1.5 && < 4.3,- Chart >= 1.5 && < 1.8,- Chart-diagrams >= 1.5 && < 1.8,+ pipes >= 4.1.5 && < 4.4,+ Chart >= 1.5 && < 1.9,+ Chart-diagrams >= 1.5 && < 1.9, diagrams-rasterific >= 1.3 && < 1.4, diagrams-lib >= 1.3 && < 1.4, readable, containers, statistics@@ -115,7 +115,7 @@ if flag(demos) build-depends: base, list-t, microlens, transformers, Frames, vector, text, template-haskell, ghc-prim, readable,- pipes >= 4.1.5 && < 4.3+ pipes >= 4.1.5 && < 4.4 hs-source-dirs: demo default-language: Haskell2010 ghc-options: -O2@@ -129,7 +129,7 @@ build-depends: base, Frames, microlens, vector, text, template-haskell, readable, foldl >= 1.1.0 && < 1.3,- pipes >= 4.1.5 && < 4.3+ pipes >= 4.1.5 && < 4.4 hs-source-dirs: demo default-language: Haskell2010 @@ -141,7 +141,7 @@ if flag(demos) build-depends: base, Frames, foldl >= 1.1.0 && < 1.3,- pipes >= 4.1.5 && < 4.3+ pipes >= 4.1.5 && < 4.4 hs-source-dirs: benchmarks default-language: Haskell2010 -- ghc-options: -O2@@ -166,7 +166,7 @@ hs-source-dirs: benchmarks main-is: InsuranceBench.hs build-depends: base, criterion, Frames, transformers,- pipes >= 4.1.5 && < 4.3+ pipes >= 4.1.5 && < 4.4 ghc-options: -O2 default-language: Haskell2010
src/Frames/CSV.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns,+ CPP, DataKinds, FlexibleInstances, KindSignatures,@@ -15,18 +16,22 @@ -- necessary types so that you can write type safe programs referring -- to those types. module Frames.CSV where+#if __GLASGOW_HASKELL__ < 710 import Control.Applicative ((<$>), pure, (<*>))-import Control.Arrow (first)+import Data.Foldable (foldMap)+import Data.Traversable (sequenceA)+import Data.Monoid (Monoid)+#endif++import Control.Arrow (first, second) import Control.Monad (MonadPlus(..), when, void) import Control.Monad.IO.Class import Data.Char (isAlpha, isAlphaNum, toLower, toUpper)-import Data.Foldable (foldMap)-import Data.Maybe (fromMaybe, isNothing)-import Data.Monoid ((<>), Monoid(..))+import Data.Maybe (isNothing)+import Data.Monoid ((<>)) import Data.Proxy import qualified Data.Text as T import qualified Data.Text.IO as T-import Data.Traversable (sequenceA) import Data.Vinyl (RElem, Rec) import Data.Vinyl.TypeLevel (RIndex) import Frames.Col@@ -240,11 +245,11 @@ -- * Template Haskell -- | Generate a column type.-recDec :: ColumnTypeable a => [(T.Text, a)] -> Q Type+recDec :: [(T.Text, Q Type)] -> Q Type recDec = appT [t|Record|] . go where go [] = return PromotedNilT go ((n,t):cs) =- [t|($(litT $ strTyLit (T.unpack n)) :-> $(colType t)) ': $(go cs) |]+ [t|($(litT $ strTyLit (T.unpack n)) :-> $(t)) ': $(go cs) |] -- | Massage a column name from a CSV file into a valid Haskell type -- identifier.@@ -376,7 +381,7 @@ tableType' (RowGen {..}) csvFile = pure . TySynD (mkName rowTypeName) [] <$> (runIO (readColHeaders opts csvFile) >>= recDec')- where recDec' = recDec :: [(T.Text, a)] -> Q Type+ where recDec' = recDec . map (second colType) :: [(T.Text, a)] -> Q Type colNames' | null columnNames = Nothing | otherwise = Just (map T.pack columnNames) opts = ParserOptions colNames' separator (RFC4180Quoting '\"')@@ -399,7 +404,7 @@ optsDec <- valD (varP optsName) (normalB $ lift opts) [] colDecs <- concat <$> mapM (uncurry $ colDec (T.pack tablePrefix)) headers return (recTy : optsTy : optsDec : colDecs)- where recDec' = recDec :: [(T.Text, a)] -> Q Type+ where recDec' = recDec . map (second colType) :: [(T.Text, a)] -> Q Type colNames' | null columnNames = Nothing | otherwise = Just (map T.pack columnNames) opts = ParserOptions colNames' separator (RFC4180Quoting '\"')@@ -423,7 +428,7 @@ return (recTy : optsTy : optsDec : colDecs) -- (:) <$> (tySynD (mkName n) [] (recDec' headers)) -- <*> (concat <$> mapM (uncurry $ colDec (T.pack prefix)) headers)- where recDec' = recDec :: [(T.Text, a)] -> Q Type+ where recDec' = recDec . map (second colType) :: [(T.Text, a)] -> Q Type colNames' | null columnNames = Nothing | otherwise = Just (map T.pack columnNames) opts = ParserOptions colNames' separator (RFC4180Quoting '\"')
src/Frames/ColumnTypeable.hs view
@@ -38,6 +38,8 @@ instance Parseable Int where instance Parseable Float where instance Parseable Double where+ -- Some CSV's export Doubles in a format like '1,000.00', filtering out commas lets us parse those sucessfully+ parse = fmap Definitely . fromText . T.filter (/= ',') instance Parseable T.Text where -- | This class relates a universe of possible column types to Haskell
src/Frames/ColumnUniverse.hs view
@@ -91,6 +91,16 @@ -- | We use a join semi-lattice on types for representations. The -- bottom of the lattice is effectively an error (we have nothing to -- represent), @Bool < Int@, @Int < Double@, and @forall n. n <= Text@.+--+-- The high-level goal here is that we will pick the "greater" of two+-- choices in 'bestRep'. A 'Definitely' parse result is preferred over+-- a 'Possibly' parse result. If we have two distinct 'Possibly' parse+-- results, we give up. If we have two distinct 'Definitely' parse+-- results, we are in dangerous waters: all data is parseable at+-- /both/ types, so which do we default to? The defaulting choices+-- made here are described in the previous paragraph. If there is no+-- defaulting rule, we give up (i.e. use 'T.Text' as a+-- representation). lubTypeReps :: Parsed TypeRep -> Parsed TypeRep -> Maybe Ordering lubTypeReps (Possibly _) (Definitely _) = Just LT lubTypeReps (Definitely _) (Possibly _) = Just GT