dataframe-core-2.2.0.0: Core data structures for the dataframe library.
Safe HaskellNone
LanguageHaskell2010

DataFrame.Typed.Schema

Synopsis

Type families for schema manipulation

type family Lookup (name :: Symbol) (cols :: [(Symbol, Type)]) where ... Source #

Look up the element type of a column by name.

Equations

Lookup name ('(name, a) ': _1) = a 
Lookup name (_1 ': rest) = Lookup name rest 
Lookup name ('[] :: [(Symbol, Type)]) = TypeError (('Text "Column '" ':<>: 'Text name) ':<>: 'Text "' not found in schema") :: Type 

type family SafeLookup (name :: Symbol) (cols :: [(Symbol, Type)]) where ... Source #

Like Lookup, but returns a harmless fallback (Int) instead of TypeError when the column is not found. Use together with AssertPresent so the error fires exactly once.

Equations

SafeLookup name ('(name, a) ': _1) = a 
SafeLookup name (_1 ': rest) = SafeLookup name rest 
SafeLookup name ('[] :: [(Symbol, Type)]) = Int 

type family HasName (name :: Symbol) (cols :: [(Symbol, Type)]) :: Bool where ... Source #

Check whether a column name exists in a schema (type-level Bool).

Equations

HasName name ('(name, _1) ': _2) = 'True 
HasName name (_1 ': rest) = HasName name rest 
HasName name ('[] :: [(Symbol, Type)]) = 'False 

type family RemoveColumn (name :: Symbol) (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Remove a column by name from a schema.

Equations

RemoveColumn name ('(name, _1) ': rest) = rest 
RemoveColumn name (col ': rest) = col ': RemoveColumn name rest 
RemoveColumn name ('[] :: [(Symbol, Type)]) = '[] :: [(Symbol, Type)] 

type family Impute (name :: Symbol) (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Unwrap a Maybe from a type after we impute values.

Equations

Impute name ('(name, Maybe a) ': rest) = '(name, a) ': rest 
Impute name ('(name, _1) ': rest) = TypeError (('Text "Column '" ':<>: 'Text name) ':<>: 'Text "' is not of kind Maybe *") :: [(Symbol, Type)] 
Impute name (col ': rest) = col ': Impute name rest 
Impute name ('[] :: [(Symbol, Type)]) = '[] :: [(Symbol, Type)] 

type family SetColumnType (name :: Symbol) b (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Equations

SetColumnType name b ('(name, _1) ': rest) = '(name, b) ': rest 
SetColumnType name b (col ': rest) = col ': SetColumnType name b rest 
SetColumnType name b ('[] :: [(Symbol, Type)]) = TypeError (('Text "Column '" ':<>: 'Text name) ':<>: 'Text "' not found in schema") :: [(Symbol, Type)] 

type family SubsetSchema (names :: [Symbol]) (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Select a subset of columns by a list of names.

Equations

SubsetSchema ('[] :: [Symbol]) cols = '[] :: [(Symbol, Type)] 
SubsetSchema (n ': ns) cols = '(n, Lookup n cols) ': SubsetSchema ns cols 

type family ExcludeSchema (names :: [Symbol]) (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Exclude columns by a list of names.

Equations

ExcludeSchema names ('[] :: [(Symbol, Type)]) = '[] :: [(Symbol, Type)] 
ExcludeSchema names ('(n, a) ': rest) = ExcludeSchemaHelper (IsElem n names) n a names rest 

type family RenameInSchema (old :: Symbol) (new :: Symbol) (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Rename a column in the schema.

Equations

RenameInSchema old new ('(old, a) ': rest) = '(new, a) ': rest 
RenameInSchema old new (col ': rest) = col ': RenameInSchema old new rest 
RenameInSchema old new ('[] :: [(Symbol, Type)]) = TypeError (('Text "Cannot rename: column '" ':<>: 'Text old) ':<>: 'Text "' not found") :: [(Symbol, Type)] 

type family RenameManyInSchema (pairs :: [(Symbol, Symbol)]) (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Rename multiple columns.

Equations

RenameManyInSchema ('[] :: [(Symbol, Symbol)]) cols = cols 
RenameManyInSchema ('(old, new) ': rest) cols = RenameManyInSchema rest (RenameInSchema old new cols) 

type family Append (xs :: [k]) (ys :: [k]) :: [k] where ... Source #

Append two type-level lists.

Equations

Append ('[] :: [k]) (ys :: [k]) = ys 
Append (x ': xs :: [k]) (ys :: [k]) = x ': Append xs ys 

type family Snoc (xs :: [k]) (x :: k) :: [k] where ... Source #

Add type to the end of a list.

Equations

Snoc ('[] :: [k]) (x :: k) = '[x] 
Snoc (y ': ys :: [k]) (x :: k) = y ': Snoc ys x 

type family Reverse (xs :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Reverse a type-level list.

Equations

Reverse xs = ReverseAcc xs ('[] :: [(Symbol, Type)]) 

type family ColumnNames (cols :: [(Symbol, Type)]) :: [Symbol] where ... Source #

Extract column names as a type-level list of Symbols.

Equations

ColumnNames ('[] :: [(Symbol, Type)]) = '[] :: [Symbol] 
ColumnNames ('(n, _1) ': rest) = n ': ColumnNames rest 

type family AssertAbsent (name :: Symbol) (cols :: [(Symbol, Type)]) where ... Source #

Assert that a column name is absent from the schema (for derive/insert).

Equations

AssertAbsent name cols = AssertAbsentHelper name (HasName name cols) cols 

type family AssertPresent (name :: Symbol) (cols :: [(Symbol, Type)]) where ... Source #

Assert that a column name is present in the schema.

Equations

AssertPresent name cols = AssertPresentHelper name (HasName name cols) cols 

type family AssertAllPresent (name :: [Symbol]) (cols :: [(Symbol, Type)]) where ... Source #

Assert that a column name is present in the schema.

Equations

AssertAllPresent (name ': rest) cols = AssertAllPresentHelper (HasName name cols) name rest cols 
AssertAllPresent ('[] :: [Symbol]) cols = () 

type family AssertKeyTypesMatch (keys :: [Symbol]) (left :: [(Symbol, Type)]) (right :: [(Symbol, Type)]) where ... Source #

Assert that each join key has the same element type in both schemas, modulo Maybe-wrapping on either side (the runtime join matches a nullable key column against a plain one). Use together with AssertAllPresent, which reports keys missing from either schema; absent keys are skipped here so the error fires exactly once.

Equations

AssertKeyTypesMatch ('[] :: [Symbol]) left right = () 
AssertKeyTypesMatch (k ': ks) left right = (KeyTypeMatchHelper k (SafeLookup k left) (SafeLookup k right), AssertKeyTypesMatch ks left right) 

type family AssertDisjoint (left :: [(Symbol, Type)]) (right :: [(Symbol, Type)]) where ... Source #

Equations

AssertDisjoint left right = AssertDisjointHelper (SharedNames left right) left right 

type family AssertAllColumnsHaveType (names :: [Symbol]) a (cols :: [(Symbol, Type)]) where ... Source #

Equations

AssertAllColumnsHaveType ('[] :: [Symbol]) a cols = () 
AssertAllColumnsHaveType (n ': ns) a cols = (SafeLookup n cols ~ a, AssertPresent n cols, AssertAllColumnsHaveType ns a cols) 

type family AssertRealColumn (fn :: Symbol) (name :: Symbol) a where ... Source #

Emit a readable compile error when the column named name is not a real-number type, naming the calling function fn, the column, and the type it actually has. Used by the numeric extractors so a wrong column type reads as a repairable message rather than a bare No instance for Real ….

Equations

AssertRealColumn fn name a = AssertRealColumnGo fn name a (IsRealType a) 

type family AllColumnsReal (fn :: Symbol) (cols :: [(Symbol, Type)]) where ... Source #

Constraint that every column in the schema is a real (numeric), unboxed type. Lets the whole-frame matrix extractors (toDoubleMatrix and friends) be total — a non-numeric or nullable column is a compile error (with the offending column named, via AssertRealColumn), not a runtime Left.

Equations

AllColumnsReal fn ('[] :: [(Symbol, Type)]) = () 
AllColumnsReal fn ('(n, a) ': rest) = (AssertRealColumn fn n a, Real a, Unbox a, AllColumnsReal fn rest) 

type family AllDouble (cols :: [(Symbol, Type)]) where ... Source #

Equations

AllDouble ('[] :: [(Symbol, Type)]) = () 
AllDouble ('(n, Double) ': rest) = AllDouble rest 
AllDouble ('(n, a) ': rest) = TypeError (((('Text "Column '" ':<>: 'Text n) ':<>: 'Text "' must be Double for this model, but is ") ':<>: 'ShowType a) ':$$: 'Text "Convert it (toDouble) or drop it before fitting.") :: Constraint 

type family IsRealType a :: Bool where ... Source #

Is a a real, unboxed numeric type — i.e. a valid numeric-column element?

type family IsElem (x :: Symbol) (xs :: [Symbol]) :: Bool where ... Source #

Type-level elem for Symbols

Equations

IsElem x ('[] :: [Symbol]) = 'False 
IsElem x (x ': _1) = 'True 
IsElem x (_1 ': xs) = IsElem x xs 

Maybe-stripping families

type family StripAllMaybe (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Strip Maybe from all columns. Used by filterAllJust.

'("x", (Maybe Double) becomes '("x", Double.)) '("y", Int stays '("y", Int.))

Equations

StripAllMaybe ('[] :: [(Symbol, Type)]) = '[] :: [(Symbol, Type)] 
StripAllMaybe ('(n, Maybe a) ': rest) = '(n, a) ': StripAllMaybe rest 
StripAllMaybe ('(n, a) ': rest) = '(n, a) ': StripAllMaybe rest 

type family StripMaybeAt (name :: Symbol) (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Strip Maybe from a single named column. Used by filterJust.

StripMaybeAt "x" '[ '("x", Maybe Double), '("y", Int)] = '[ '("x", Double), '("y", Int)]

Equations

StripMaybeAt name ('(name, Maybe a) ': rest) = '(name, a) ': rest 
StripMaybeAt name ('(name, a) ': rest) = '(name, a) ': rest 
StripMaybeAt name (col ': rest) = col ': StripMaybeAt name rest 
StripMaybeAt name ('[] :: [(Symbol, Type)]) = TypeError (('Text "Column '" ':<>: 'Text name) ':<>: 'Text "' not found in schema") :: [(Symbol, Type)] 

Join schema families

type family SharedNames (left :: [(Symbol, Type)]) (right :: [(Symbol, Type)]) :: [Symbol] where ... Source #

Extract column names that appear in both schemas.

Equations

SharedNames ('[] :: [(Symbol, Type)]) right = '[] :: [Symbol] 
SharedNames ('(n, _1) ': rest) right = SharedNamesHelper (HasName n right) n rest right 

type family UniqueLeft (left :: [(Symbol, Type)]) (rightNames :: [Symbol]) :: [(Symbol, Type)] where ... Source #

Columns from left whose names do NOT appear in right.

Equations

UniqueLeft ('[] :: [(Symbol, Type)]) _1 = '[] :: [(Symbol, Type)] 
UniqueLeft ('(n, a) ': rest) rn = UniqueLeftHelper (IsElem n rn) n a rest rn 

type family InnerJoinSchema (keys :: [Symbol]) (left :: [(Symbol, Type)]) (right :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Inner join result schema.

Equations

InnerJoinSchema keys left right = Append (SubsetSchema keys left) (Append (UniqueLeft left (Append keys (ColumnNames right))) (Append (UniqueLeft right (Append keys (ColumnNames left))) (CollidingColumns left right keys))) 

type family LeftJoinSchema (keys :: [Symbol]) (left :: [(Symbol, Type)]) (right :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Left join result schema.

Equations

LeftJoinSchema keys left right = Append (SubsetSchema keys left) (Append (UniqueLeft left (Append keys (ColumnNames right))) (Append (WrapMaybe (UniqueLeft right (Append keys (ColumnNames left)))) (CollidingColumns left right keys))) 

type family RightJoinSchema (keys :: [Symbol]) (left :: [(Symbol, Type)]) (right :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Right join result schema.

Equations

RightJoinSchema keys left right = Append (SubsetSchema keys right) (Append (WrapMaybe (UniqueLeft left (Append keys (ColumnNames right)))) (Append (UniqueLeft right (Append keys (ColumnNames left))) (CollidingColumns left right keys))) 

type family FullOuterJoinSchema (keys :: [Symbol]) (left :: [(Symbol, Type)]) (right :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Full outer join result schema.

Equations

FullOuterJoinSchema keys left right = Append (WrapMaybe (SubsetSchema keys left)) (Append (WrapMaybe (UniqueLeft left (Append keys (ColumnNames right)))) (Append (WrapMaybe (UniqueLeft right (Append keys (ColumnNames left)))) (CollidingColumns left right keys))) 

type family ToMaybe a where ... Source #

Equations

ToMaybe (Maybe a) = Maybe a 
ToMaybe a = Maybe a 

type family WrapMaybe (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Wrap column types in Maybe; idempotent on already-optional columns.

Equations

WrapMaybe ('[] :: [(Symbol, Type)]) = '[] :: [(Symbol, Type)] 
WrapMaybe ('(n, a) ': rest) = '(n, ToMaybe a) ': WrapMaybe rest 

type family WrapMaybeColumns (names :: [Symbol]) (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Wrap selected columns in Maybe by name list.

Equations

WrapMaybeColumns names ('[] :: [(Symbol, Type)]) = '[] :: [(Symbol, Type)] 
WrapMaybeColumns names ('(n, a) ': rest) = WrapMaybeColumnsHelper (IsElem n names) n a names rest 

type family CollidingColumns (left :: [(Symbol, Type)]) (right :: [(Symbol, Type)]) (keys :: [Symbol]) :: [(Symbol, Type)] where ... Source #

Columns in left whose names collide with right (excluding keys).

Equations

CollidingColumns ('[] :: [(Symbol, Type)]) _1 _2 = '[] :: [(Symbol, Type)] 
CollidingColumns ('(n, a) ': rest) right keys = CollidingColumnsHelper1 (IsElem n keys) n a rest right keys 

GroupBy helpers

type family GroupKeyColumns (keys :: [Symbol]) (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where ... Source #

Extract Column entries from a schema whose names appear in keys.

Equations

GroupKeyColumns keys ('[] :: [(Symbol, Type)]) = '[] :: [(Symbol, Type)] 
GroupKeyColumns keys ('(n, a) ': rest) = GroupKeyColumnsHelper (IsElem n keys) n a keys rest 

KnownSchema class

class KnownSchema (cols :: [(Symbol, Type)]) where Source #

Provides runtime evidence of a schema: a list of (name, TypeRep) pairs.

Instances

Instances details
KnownSchema ('[] :: [(Symbol, Type)]) Source # 
Instance details

Defined in DataFrame.Typed.Schema

(KnownSymbol name, Typeable a, Columnable a, KnownSchema rest) => KnownSchema ('(name, a) ': rest) Source # 
Instance details

Defined in DataFrame.Typed.Schema

schemaColumnNames :: forall (cols :: [(Symbol, Type)]). KnownSchema cols => [Text] Source #

The column names a schema declares, in schema order. Pass it to a reader's options to fetch only those columns:

D.readCsvWithOpts
    D.defaultReadOptions{D.readColumns = Just (schemaColumnNames @(Schema Customer))}
    "customers.csv"

Helpers

class AllKnownSymbol (names :: [Symbol]) where Source #

A class that provides a list of Text values for a type-level list of Symbols.

Methods

symbolVals :: [Text] Source #

Instances

Instances details
AllKnownSymbol ('[] :: [Symbol]) Source # 
Instance details

Defined in DataFrame.Typed.Schema

Methods

symbolVals :: [Text] Source #

(KnownSymbol n, AllKnownSymbol ns) => AllKnownSymbol (n ': ns) Source # 
Instance details

Defined in DataFrame.Typed.Schema

Methods

symbolVals :: [Text] Source #