packages feed

dataframe-core 2.1.1.2 → 2.2.0.0

raw patch · 5 files changed

+168/−118 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- DataFrame.Typed.Schema: instance (GHC.TypeLits.KnownSymbol name, Data.Typeable.Internal.Typeable a, DataFrame.Internal.Column.Columnable a, DataFrame.Typed.Schema.KnownSchema rest) => DataFrame.Typed.Schema.KnownSchema (DataFrame.Typed.Types.Column name a : rest)
- DataFrame.Typed.Types: data Column (name :: Symbol) a
+ DataFrame.Typed.Schema: instance (GHC.TypeLits.KnownSymbol name, Data.Typeable.Internal.Typeable a, DataFrame.Internal.Column.Columnable a, DataFrame.Typed.Schema.KnownSchema rest) => DataFrame.Typed.Schema.KnownSchema ('(name, a) : rest)
- DataFrame.Typed.Freeze: freeze :: forall (cols :: [Type]). KnownSchema cols => DataFrame -> Maybe (TypedDataFrame cols)
+ DataFrame.Typed.Freeze: freeze :: forall (cols :: [(Symbol, Type)]). KnownSchema cols => DataFrame -> Maybe (TypedDataFrame cols)
- DataFrame.Typed.Freeze: freezeOrThrow :: forall (cols :: [Type]). KnownSchema cols => DataFrame -> IO (TypedDataFrame cols)
+ DataFrame.Typed.Freeze: freezeOrThrow :: forall (cols :: [(Symbol, Type)]). KnownSchema cols => DataFrame -> IO (TypedDataFrame cols)
- DataFrame.Typed.Freeze: freezeWithError :: forall (cols :: [Type]). KnownSchema cols => DataFrame -> Either Text (TypedDataFrame cols)
+ DataFrame.Typed.Freeze: freezeWithError :: forall (cols :: [(Symbol, Type)]). KnownSchema cols => DataFrame -> Either Text (TypedDataFrame cols)
- DataFrame.Typed.Freeze: thaw :: forall (cols :: [Type]). TypedDataFrame cols -> DataFrame
+ DataFrame.Typed.Freeze: thaw :: forall (cols :: [(Symbol, Type)]). TypedDataFrame cols -> DataFrame
- DataFrame.Typed.Freeze: unsafeFreeze :: forall (cols :: [Type]). DataFrame -> TypedDataFrame cols
+ DataFrame.Typed.Freeze: unsafeFreeze :: forall (cols :: [(Symbol, Type)]). DataFrame -> TypedDataFrame cols
- DataFrame.Typed.Record: type Schema a :: [Type];
+ DataFrame.Typed.Record: type Schema a :: [(Symbol, Type)];
- DataFrame.Typed.Schema: class KnownSchema (cols :: [Type])
+ DataFrame.Typed.Schema: class KnownSchema (cols :: [(Symbol, Type)])
- DataFrame.Typed.Schema: schemaColumnNames :: forall (cols :: [Type]). KnownSchema cols => [Text]
+ DataFrame.Typed.Schema: schemaColumnNames :: forall (cols :: [(Symbol, Type)]). KnownSchema cols => [Text]
- DataFrame.Typed.Schema: type family GroupKeyColumns (keys :: [Symbol]) (cols :: [Type]) :: [Type]
+ DataFrame.Typed.Schema: type family GroupKeyColumns (keys :: [Symbol]) (cols :: [(Symbol, Type)]) :: [(Symbol, Type)]
- DataFrame.Typed.Types: TDF :: DataFrame -> TypedDataFrame (cols :: [Type])
+ DataFrame.Typed.Types: TDF :: DataFrame -> TypedDataFrame (cols :: [(Symbol, Type)])
- DataFrame.Typed.Types: TExpr :: Expr a -> TExpr (cols :: [Type]) a
+ DataFrame.Typed.Types: TExpr :: Expr a -> TExpr (cols :: [(Symbol, Type)]) a
- DataFrame.Typed.Types: TGD :: GroupedDataFrame -> TypedGrouped (keys :: [Symbol]) (cols :: [Type])
+ DataFrame.Typed.Types: TGD :: GroupedDataFrame -> TypedGrouped (keys :: [Symbol]) (cols :: [(Symbol, Type)])
- DataFrame.Typed.Types: [Asc] :: forall a (cols :: [Type]). (Columnable a, Ord a) => TExpr cols a -> TSortOrder cols
+ DataFrame.Typed.Types: [Asc] :: forall a (cols :: [(Symbol, Type)]). (Columnable a, Ord a) => TExpr cols a -> TSortOrder cols
- DataFrame.Typed.Types: [Desc] :: forall a (cols :: [Type]). (Columnable a, Ord a) => TExpr cols a -> TSortOrder cols
+ DataFrame.Typed.Types: [Desc] :: forall a (cols :: [(Symbol, Type)]). (Columnable a, Ord a) => TExpr cols a -> TSortOrder cols
- DataFrame.Typed.Types: [TAggCons] :: forall a (cols :: [Type]) (keys :: [Symbol]) (aggs1 :: [Type]) (name :: Symbol). Columnable a => Text -> TExpr cols a -> TAgg keys cols aggs1 -> TAgg keys cols (Column name a ': aggs1)
+ DataFrame.Typed.Types: [TAggCons] :: forall a (cols :: [(Symbol, Type)]) (keys :: [Symbol]) (aggs1 :: [(Symbol, Type)]) (name :: Symbol). Columnable a => Text -> TExpr cols a -> TAgg keys cols aggs1 -> TAgg keys cols ('(name, a) ': aggs1)
- DataFrame.Typed.Types: [TAggNil] :: forall (keys :: [Symbol]) (cols :: [Type]). TAgg keys cols ('[] :: [Type])
+ DataFrame.Typed.Types: [TAggNil] :: forall (keys :: [Symbol]) (cols :: [(Symbol, Type)]). TAgg keys cols ('[] :: [(Symbol, Type)])
- DataFrame.Typed.Types: [unTDF] :: TypedDataFrame (cols :: [Type]) -> DataFrame
+ DataFrame.Typed.Types: [unTDF] :: TypedDataFrame (cols :: [(Symbol, Type)]) -> DataFrame
- DataFrame.Typed.Types: [unTExpr] :: TExpr (cols :: [Type]) a -> Expr a
+ DataFrame.Typed.Types: [unTExpr] :: TExpr (cols :: [(Symbol, Type)]) a -> Expr a
- DataFrame.Typed.Types: [unTGD] :: TypedGrouped (keys :: [Symbol]) (cols :: [Type]) -> GroupedDataFrame
+ DataFrame.Typed.Types: [unTGD] :: TypedGrouped (keys :: [Symbol]) (cols :: [(Symbol, Type)]) -> GroupedDataFrame
- DataFrame.Typed.Types: class ToTExpr (cols :: [Type]) e
+ DataFrame.Typed.Types: class ToTExpr (cols :: [(Symbol, Type)]) e
- DataFrame.Typed.Types: data TAgg (keys :: [Symbol]) (cols :: [Type]) (aggs :: [Type])
+ DataFrame.Typed.Types: data TAgg (keys :: [Symbol]) (cols :: [(Symbol, Type)]) (aggs :: [(Symbol, Type)])
- DataFrame.Typed.Types: data TSortOrder (cols :: [Type])
+ DataFrame.Typed.Types: data TSortOrder (cols :: [(Symbol, Type)])
- DataFrame.Typed.Types: newtype TExpr (cols :: [Type]) a
+ DataFrame.Typed.Types: newtype TExpr (cols :: [(Symbol, Type)]) a
- DataFrame.Typed.Types: newtype TypedDataFrame (cols :: [Type])
+ DataFrame.Typed.Types: newtype TypedDataFrame (cols :: [(Symbol, Type)])
- DataFrame.Typed.Types: newtype TypedGrouped (keys :: [Symbol]) (cols :: [Type])
+ DataFrame.Typed.Types: newtype TypedGrouped (keys :: [Symbol]) (cols :: [(Symbol, Type)])
- DataFrame.Typed.Types: taggToNamedExprs :: forall (keys :: [Symbol]) (cols :: [Type]) (aggs :: [Type]). TAgg keys cols aggs -> [NamedExpr]
+ DataFrame.Typed.Types: taggToNamedExprs :: forall (keys :: [Symbol]) (cols :: [(Symbol, Type)]) (aggs :: [(Symbol, Type)]). TAgg keys cols aggs -> [NamedExpr]
- DataFrame.Typed.Types: type family AsTExpr (cols :: [Type]) e
+ DataFrame.Typed.Types: type family AsTExpr (cols :: [(Symbol, Type)]) e

Files

dataframe-core.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.4 name:               dataframe-core-version:            2.1.1.2+version:            2.2.0.0 synopsis:           Core data structures for the dataframe library. description:     Minimal interchange-format types for the @dataframe@ ecosystem:
src/DataFrame/Typed/Generic.hs view
@@ -86,7 +86,6 @@ import qualified DataFrame.Internal.DataFrame as D import DataFrame.Typed.Record (requireColumn) import DataFrame.Typed.Schema (Append)-import DataFrame.Typed.Types (Column) import DataFrame.Typed.Util (camelToSnake)  {- | Field-name policy applied to record selectors when computing@@ -97,15 +96,15 @@ -} data NameCase = SnakeCase | IdentityCase -{- | The schema type @[Column name ty, ...]@ derived from the 'Rep' of a+{- | The schema type @'[ '(name, ty), ...]@ derived from the 'Rep' of a record type, with the given 'NameCase' applied to each field name. -}-type family RepToSchema (nc :: NameCase) (r :: Type -> Type) :: [Type] where+type family RepToSchema (nc :: NameCase) (r :: Type -> Type) :: [(Symbol, Type)] where     RepToSchema nc (M1 D _ f) = RepToSchema nc f     RepToSchema nc (M1 C _ f) = RepToSchema nc f     RepToSchema nc (a :*: b) = Append (RepToSchema nc a) (RepToSchema nc b)     RepToSchema nc (M1 S ('MetaSel ('Just name) _ _ _) (K1 _ a)) =-        '[Column (TransformName nc name) a]+        '(TransformName nc name, a) ': '[]  type family TransformName (nc :: NameCase) (name :: Symbol) :: Symbol where     TransformName 'SnakeCase s = CamelToSnake s
src/DataFrame/Typed/Record.hs view
@@ -38,6 +38,7 @@ import DataFrame.Internal.DataFrame (fromNamedColumns) import qualified DataFrame.Internal.DataFrame as D import DataFrame.Typed.Types (TypedDataFrame (..))+import GHC.TypeLits  {- | Bridge a Haskell record type @a@ to a typed-dataframe schema. @@ -51,7 +52,7 @@ @Left err@ if a column is missing or has the wrong type. -} class HasSchema a where-    type Schema a :: [Type]+    type Schema a :: [(Symbol, Type)]     toColumns :: [a] -> [(T.Text, C.Column)]     fromColumns :: D.DataFrame -> Either T.Text [a] 
src/DataFrame/Typed/Schema.hs view
@@ -79,12 +79,11 @@  import DataFrame.Internal.Column (Columnable) import DataFrame.Internal.Types (These)-import DataFrame.Typed.Types (Column)  -- | Look up the element type of a column by name.-type family Lookup (name :: Symbol) (cols :: [Type]) :: Type where-    Lookup name (Column name a ': _) = a-    Lookup name (Column _ _ ': rest) = Lookup name rest+type family Lookup (name :: Symbol) (cols :: [(Symbol, Type)]) :: Type where+    Lookup name ('(name, a) ': _) = a+    Lookup name (_ ': rest) = Lookup name rest     Lookup name '[] =         TypeError             ('Text "Column '" ':<>: 'Text name ':<>: 'Text "' not found in schema")@@ -93,22 +92,25 @@ 'TypeError' when the column is not found.  Use together with 'AssertPresent' so the error fires exactly once. -}-type family SafeLookup (name :: Symbol) (cols :: [Type]) :: Type where-    SafeLookup name (Column name a ': _) = a-    SafeLookup name (Column _ _ ': rest) = SafeLookup name rest+type family SafeLookup (name :: Symbol) (cols :: [(Symbol, Type)]) :: Type where+    SafeLookup name ('(name, a) ': _) = a+    SafeLookup name (_ ': rest) = SafeLookup name rest     SafeLookup name '[] = Int  -- | Unwrap a Maybe from a type after we impute values.-type family Impute (name :: Symbol) (cols :: [Type]) :: [Type] where-    Impute name (Column name (Maybe a) ': rest) = Column name a ': rest-    Impute name (Column name _ ': rest) =+type family Impute (name :: Symbol) (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where+    Impute name ('(name, Maybe a) ': rest) = '(name, a) ': rest+    Impute name ('(name, _) ': rest) =         TypeError             ('Text "Column '" ':<>: 'Text name ':<>: 'Text "' is not of kind Maybe *")     Impute name (col ': rest) = col ': Impute name rest     Impute name '[] = '[] -type family SetColumnType (name :: Symbol) (b :: Type) (cols :: [Type]) :: [Type] where-    SetColumnType name b (Column name _ ': rest) = Column name b ': rest+type family+    SetColumnType (name :: Symbol) (b :: Type) (cols :: [(Symbol, Type)]) ::+        [(Symbol, Type)]+    where+    SetColumnType name b ('(name, _) ': rest) = '(name, b) ': rest     SetColumnType name b (col ': rest) = col ': SetColumnType name b rest     SetColumnType name b '[] =         TypeError@@ -120,26 +122,26 @@     Snoc (y ': ys) x = y ': Snoc ys x  -- | Check whether a column name exists in a schema (type-level Bool).-type family HasName (name :: Symbol) (cols :: [Type]) :: Bool where-    HasName name (Column name _ ': _) = 'True-    HasName name (Column _ _ ': rest) = HasName name rest+type family HasName (name :: Symbol) (cols :: [(Symbol, Type)]) :: Bool where+    HasName name ('(name, _) ': _) = 'True+    HasName name (_ ': rest) = HasName name rest     HasName name '[] = 'False  -- | Remove a column by name from a schema.-type family RemoveColumn (name :: Symbol) (cols :: [Type]) :: [Type] where-    RemoveColumn name (Column name _ ': rest) = rest+type family RemoveColumn (name :: Symbol) (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where+    RemoveColumn name ('(name, _) ': rest) = rest     RemoveColumn name (col ': rest) = col ': RemoveColumn name rest     RemoveColumn name '[] = '[]  -- | Select a subset of columns by a list of names.-type family SubsetSchema (names :: [Symbol]) (cols :: [Type]) :: [Type] where+type family SubsetSchema (names :: [Symbol]) (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where     SubsetSchema '[] cols = '[]-    SubsetSchema (n ': ns) cols = Column n (Lookup n cols) ': SubsetSchema ns cols+    SubsetSchema (n ': ns) cols = '(n, Lookup n cols) ': SubsetSchema ns cols  -- | Exclude columns by a list of names.-type family ExcludeSchema (names :: [Symbol]) (cols :: [Type]) :: [Type] where+type family ExcludeSchema (names :: [Symbol]) (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where     ExcludeSchema names '[] = '[]-    ExcludeSchema names (Column n a ': rest) =+    ExcludeSchema names ('(n, a) ': rest) =         ExcludeSchemaHelper (IsElem n names) n a names rest  type family@@ -148,12 +150,12 @@         (n :: Symbol)         (a :: Type)         (names :: [Symbol])-        (rest :: [Type]) ::-        [Type]+        (rest :: [(Symbol, Type)]) ::+        [(Symbol, Type)]     where     ExcludeSchemaHelper 'True n a names rest = ExcludeSchema names rest     ExcludeSchemaHelper 'False n a names rest =-        Column n a ': ExcludeSchema names rest+        '(n, a) ': ExcludeSchema names rest  -- | Type-level elem for Symbols type family IsElem (x :: Symbol) (xs :: [Symbol]) :: Bool where@@ -162,15 +164,21 @@     IsElem x (_ ': xs) = IsElem x xs  -- | Rename a column in the schema.-type family RenameInSchema (old :: Symbol) (new :: Symbol) (cols :: [Type]) :: [Type] where-    RenameInSchema old new (Column old a ': rest) = Column new a ': rest+type family+    RenameInSchema (old :: Symbol) (new :: Symbol) (cols :: [(Symbol, Type)]) ::+        [(Symbol, Type)]+    where+    RenameInSchema old new ('(old, a) ': rest) = '(new, a) ': rest     RenameInSchema old new (col ': rest) = col ': RenameInSchema old new rest     RenameInSchema old new '[] =         TypeError             ('Text "Cannot rename: column '" ':<>: 'Text old ':<>: 'Text "' not found")  -- | Rename multiple columns.-type family RenameManyInSchema (pairs :: [(Symbol, Symbol)]) (cols :: [Type]) :: [Type] where+type family+    RenameManyInSchema (pairs :: [(Symbol, Symbol)]) (cols :: [(Symbol, Type)]) ::+        [(Symbol, Type)]+    where     RenameManyInSchema '[] cols = cols     RenameManyInSchema ('(old, new) ': rest) cols =         RenameManyInSchema rest (RenameInSchema old new cols)@@ -181,24 +189,27 @@     Append (x ': xs) ys = x ': Append xs ys  -- | Reverse a type-level list.-type family Reverse (xs :: [Type]) :: [Type] where+type family Reverse (xs :: [(Symbol, Type)]) :: [(Symbol, Type)] where     Reverse xs = ReverseAcc xs '[] -type family ReverseAcc (xs :: [Type]) (acc :: [Type]) :: [Type] where+type family+    ReverseAcc (xs :: [(Symbol, Type)]) (acc :: [(Symbol, Type)]) ::+        [(Symbol, Type)]+    where     ReverseAcc '[] acc = acc     ReverseAcc (x ': xs) acc = ReverseAcc xs (x ': acc)  -- | Extract column names as a type-level list of Symbols.-type family ColumnNames (cols :: [Type]) :: [Symbol] where+type family ColumnNames (cols :: [(Symbol, Type)]) :: [Symbol] where     ColumnNames '[] = '[]-    ColumnNames (Column n _ ': rest) = n ': ColumnNames rest+    ColumnNames ('(n, _) ': rest) = n ': ColumnNames rest  -- | Assert that a column name is absent from the schema (for derive/insert).-type family AssertAbsent (name :: Symbol) (cols :: [Type]) :: Constraint where+type family AssertAbsent (name :: Symbol) (cols :: [(Symbol, Type)]) :: Constraint where     AssertAbsent name cols = AssertAbsentHelper name (HasName name cols) cols  type family-    AssertAbsentHelper (name :: Symbol) (found :: Bool) (cols :: [Type]) ::+    AssertAbsentHelper (name :: Symbol) (found :: Bool) (cols :: [(Symbol, Type)]) ::         Constraint     where     AssertAbsentHelper name 'False cols = ()@@ -211,11 +222,11 @@             )  -- | Assert that a column name is present in the schema.-type family AssertPresent (name :: Symbol) (cols :: [Type]) :: Constraint where+type family AssertPresent (name :: Symbol) (cols :: [(Symbol, Type)]) :: Constraint where     AssertPresent name cols = AssertPresentHelper name (HasName name cols) cols  type family-    AssertPresentHelper (name :: Symbol) (found :: Bool) (cols :: [Type]) ::+    AssertPresentHelper (name :: Symbol) (found :: Bool) (cols :: [(Symbol, Type)]) ::         Constraint     where     AssertPresentHelper name 'True cols = ()@@ -224,7 +235,7 @@             ('Text "Column '" ':<>: 'Text name ':<>: 'Text "' not found in schema")  -- | Assert that a column name is present in the schema.-type family AssertAllPresent (name :: [Symbol]) (cols :: [Type]) :: Constraint where+type family AssertAllPresent (name :: [Symbol]) (cols :: [(Symbol, Type)]) :: Constraint where     AssertAllPresent (name ': rest) cols =         AssertAllPresentHelper (HasName name cols) name rest cols     AssertAllPresent '[] cols = ()@@ -234,7 +245,7 @@         (found :: Bool)         (name :: Symbol)         (rest :: [Symbol])-        (cols :: [Type]) ::+        (cols :: [(Symbol, Type)]) ::         Constraint     where     AssertAllPresentHelper 'True name rest cols = AssertAllPresent rest cols@@ -249,7 +260,10 @@ error fires exactly once. -} type family-    AssertKeyTypesMatch (keys :: [Symbol]) (left :: [Type]) (right :: [Type]) ::+    AssertKeyTypesMatch+        (keys :: [Symbol])+        (left :: [(Symbol, Type)])+        (right :: [(Symbol, Type)]) ::         Constraint     where     AssertKeyTypesMatch '[] left right = ()@@ -276,12 +290,18 @@                 ':<>: 'Text " in the right table"             ) -type family AssertDisjoint (left :: [Type]) (right :: [Type]) :: Constraint where+type family+    AssertDisjoint (left :: [(Symbol, Type)]) (right :: [(Symbol, Type)]) ::+        Constraint+    where     AssertDisjoint left right =         AssertDisjointHelper (SharedNames left right) left right  type family-    AssertDisjointHelper (shared :: [Symbol]) (left :: [Type]) (right :: [Type]) ::+    AssertDisjointHelper+        (shared :: [Symbol])+        (left :: [(Symbol, Type)])+        (right :: [(Symbol, Type)]) ::         Constraint     where     AssertDisjointHelper '[] left right = ()@@ -293,7 +313,10 @@             )  type family-    AssertAllColumnsHaveType (names :: [Symbol]) (a :: Type) (cols :: [Type]) ::+    AssertAllColumnsHaveType+        (names :: [Symbol])+        (a :: Type)+        (cols :: [(Symbol, Type)]) ::         Constraint     where     AssertAllColumnsHaveType '[] a cols = ()@@ -346,16 +369,16 @@ total — a non-numeric or nullable column is a compile error (with the offending column named, via 'AssertRealColumn'), not a runtime 'Left'. -}-type family AllColumnsReal (fn :: Symbol) (cols :: [Type]) :: Constraint where+type family AllColumnsReal (fn :: Symbol) (cols :: [(Symbol, Type)]) :: Constraint where     AllColumnsReal fn '[] = ()-    AllColumnsReal fn (Column n a ': rest) =+    AllColumnsReal fn ('(n, a) ': rest) =         (AssertRealColumn fn n a, Real a, VU.Unbox a, AllColumnsReal fn rest)  -- TODO: mchavinda - we can generalist to AllX-type family AllDouble (cols :: [Type]) :: Constraint where+type family AllDouble (cols :: [(Symbol, Type)]) :: Constraint where     AllDouble '[] = ()-    AllDouble (Column n Double ': rest) = AllDouble rest-    AllDouble (Column n a ': rest) =+    AllDouble ('(n, Double) ': rest) = AllDouble rest+    AllDouble ('(n, a) ': rest) =         TypeError             ( 'Text "Column '"                 ':<>: 'Text n@@ -366,48 +389,51 @@  {- | Strip 'Maybe' from all columns. Used by 'filterAllJust'. -@Column "x" (Maybe Double)@ becomes @Column "x" Double@.-@Column "y" Int@ stays @Column "y" Int@.+@'("x", (Maybe Double)@ becomes @'("x", Double@.))+@'("y", Int@ stays @'("y", Int@.)) -}-type family StripAllMaybe (cols :: [Type]) :: [Type] where+type family StripAllMaybe (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where     StripAllMaybe '[] = '[]-    StripAllMaybe (Column n (Maybe a) ': rest) = Column n a ': StripAllMaybe rest-    StripAllMaybe (Column n a ': rest) = Column n a ': StripAllMaybe rest+    StripAllMaybe ('(n, Maybe a) ': rest) = '(n, a) ': StripAllMaybe rest+    StripAllMaybe ('(n, a) ': rest) = '(n, a) ': StripAllMaybe rest  {- | Strip 'Maybe' from a single named column. Used by 'filterJust'. -@StripMaybeAt "x" '[Column "x" (Maybe Double), Column "y" Int]@-  = @'[Column "x" Double, Column "y" Int]@+@StripMaybeAt "x" '[ '("x", Maybe Double), '("y", Int)]@+  = @'[ '("x", Double), '("y", Int)]@ -}-type family StripMaybeAt (name :: Symbol) (cols :: [Type]) :: [Type] where-    StripMaybeAt name (Column name (Maybe a) ': rest) = Column name a ': rest-    StripMaybeAt name (Column name a ': rest) = Column name a ': rest+type family StripMaybeAt (name :: Symbol) (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where+    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 '[] =         TypeError             ('Text "Column '" ':<>: 'Text name ':<>: 'Text "' not found in schema")  -- | Extract column names that appear in both schemas.-type family SharedNames (left :: [Type]) (right :: [Type]) :: [Symbol] where+type family SharedNames (left :: [(Symbol, Type)]) (right :: [(Symbol, Type)]) :: [Symbol] where     SharedNames '[] right = '[]-    SharedNames (Column n _ ': rest) right =+    SharedNames ('(n, _) ': rest) right =         SharedNamesHelper (HasName n right) n rest right  type family     SharedNamesHelper         (found :: Bool)         (n :: Symbol)-        (rest :: [Type])-        (right :: [Type]) ::+        (rest :: [(Symbol, Type)])+        (right :: [(Symbol, Type)]) ::         [Symbol]     where     SharedNamesHelper 'True n rest right = n ': SharedNames rest right     SharedNamesHelper 'False n rest right = SharedNames rest right  -- | Columns from @left@ whose names do NOT appear in @right@.-type family UniqueLeft (left :: [Type]) (rightNames :: [Symbol]) :: [Type] where+type family+    UniqueLeft (left :: [(Symbol, Type)]) (rightNames :: [Symbol]) ::+        [(Symbol, Type)]+    where     UniqueLeft '[] _ = '[]-    UniqueLeft (Column n a ': rest) rn =+    UniqueLeft ('(n, a) ': rest) rn =         UniqueLeftHelper (IsElem n rn) n a rest rn  type family@@ -415,26 +441,29 @@         (found :: Bool)         (n :: Symbol)         (a :: Type)-        (rest :: [Type])+        (rest :: [(Symbol, Type)])         (rn :: [Symbol]) ::-        [Type]+        [(Symbol, Type)]     where     UniqueLeftHelper 'True n a rest rn = UniqueLeft rest rn-    UniqueLeftHelper 'False n a rest rn = Column n a ': UniqueLeft rest rn+    UniqueLeftHelper 'False n a rest rn = '(n, a) ': UniqueLeft rest rn  type family ToMaybe (a :: Type) :: Type where     ToMaybe (Maybe a) = Maybe a     ToMaybe a = Maybe a  -- | Wrap column types in Maybe; idempotent on already-optional columns.-type family WrapMaybe (cols :: [Type]) :: [Type] where+type family WrapMaybe (cols :: [(Symbol, Type)]) :: [(Symbol, Type)] where     WrapMaybe '[] = '[]-    WrapMaybe (Column n a ': rest) = Column n (ToMaybe a) ': WrapMaybe rest+    WrapMaybe ('(n, a) ': rest) = '(n, ToMaybe a) ': WrapMaybe rest  -- | Wrap selected columns in Maybe by name list.-type family WrapMaybeColumns (names :: [Symbol]) (cols :: [Type]) :: [Type] where+type family+    WrapMaybeColumns (names :: [Symbol]) (cols :: [(Symbol, Type)]) ::+        [(Symbol, Type)]+    where     WrapMaybeColumns names '[] = '[]-    WrapMaybeColumns names (Column n a ': rest) =+    WrapMaybeColumns names ('(n, a) ': rest) =         WrapMaybeColumnsHelper (IsElem n names) n a names rest  type family@@ -443,18 +472,24 @@         (n :: Symbol)         (a :: Type)         (names :: [Symbol])-        (rest :: [Type]) ::-        [Type]+        (rest :: [(Symbol, Type)]) ::+        [(Symbol, Type)]     where     WrapMaybeColumnsHelper 'True n a names rest =-        Column n (ToMaybe a) ': WrapMaybeColumns names rest+        '(n, ToMaybe a) ': WrapMaybeColumns names rest     WrapMaybeColumnsHelper 'False n a names rest =-        Column n a ': WrapMaybeColumns names rest+        '(n, a) ': WrapMaybeColumns names rest  -- | Columns in left whose names collide with right (excluding keys).-type family CollidingColumns (left :: [Type]) (right :: [Type]) (keys :: [Symbol]) :: [Type] where+type family+    CollidingColumns+        (left :: [(Symbol, Type)])+        (right :: [(Symbol, Type)])+        (keys :: [Symbol]) ::+        [(Symbol, Type)]+    where     CollidingColumns '[] _ _ = '[]-    CollidingColumns (Column n a ': rest) right keys =+    CollidingColumns ('(n, a) ': rest) right keys =         CollidingColumnsHelper1 (IsElem n keys) n a rest right keys  type family@@ -462,10 +497,10 @@         (isKey :: Bool)         (n :: Symbol)         (a :: Type)-        (rest :: [Type])-        (right :: [Type])+        (rest :: [(Symbol, Type)])+        (right :: [(Symbol, Type)])         (keys :: [Symbol]) ::-        [Type]+        [(Symbol, Type)]     where     CollidingColumnsHelper1 'True n a rest right keys =         CollidingColumns rest right keys@@ -477,18 +512,24 @@         (inRight :: Bool)         (n :: Symbol)         (a :: Type)-        (rest :: [Type])-        (right :: [Type])+        (rest :: [(Symbol, Type)])+        (right :: [(Symbol, Type)])         (keys :: [Symbol]) ::-        [Type]+        [(Symbol, Type)]     where     CollidingColumnsHelper2 'True n a rest right keys =-        Column n (These a (Lookup n right)) ': CollidingColumns rest right keys+        '(n, These a (Lookup n right)) ': CollidingColumns rest right keys     CollidingColumnsHelper2 'False n a rest right keys =         CollidingColumns rest right keys  -- | Inner join result schema.-type family InnerJoinSchema (keys :: [Symbol]) (left :: [Type]) (right :: [Type]) :: [Type] where+type family+    InnerJoinSchema+        (keys :: [Symbol])+        (left :: [(Symbol, Type)])+        (right :: [(Symbol, Type)]) ::+        [(Symbol, Type)]+    where     InnerJoinSchema keys left right =         Append             (SubsetSchema keys left)@@ -501,7 +542,13 @@             )  -- | Left join result schema.-type family LeftJoinSchema (keys :: [Symbol]) (left :: [Type]) (right :: [Type]) :: [Type] where+type family+    LeftJoinSchema+        (keys :: [Symbol])+        (left :: [(Symbol, Type)])+        (right :: [(Symbol, Type)]) ::+        [(Symbol, Type)]+    where     LeftJoinSchema keys left right =         Append             (SubsetSchema keys left)@@ -514,7 +561,13 @@             )  -- | Right join result schema.-type family RightJoinSchema (keys :: [Symbol]) (left :: [Type]) (right :: [Type]) :: [Type] where+type family+    RightJoinSchema+        (keys :: [Symbol])+        (left :: [(Symbol, Type)])+        (right :: [(Symbol, Type)]) ::+        [(Symbol, Type)]+    where     RightJoinSchema keys left right =         Append             (SubsetSchema keys right)@@ -528,8 +581,11 @@  -- | Full outer join result schema. type family-    FullOuterJoinSchema (keys :: [Symbol]) (left :: [Type]) (right :: [Type]) ::-        [Type]+    FullOuterJoinSchema+        (keys :: [Symbol])+        (left :: [(Symbol, Type)])+        (right :: [(Symbol, Type)]) ::+        [(Symbol, Type)]     where     FullOuterJoinSchema keys left right =         Append@@ -543,9 +599,12 @@             )  -- | Extract Column entries from a schema whose names appear in @keys@.-type family GroupKeyColumns (keys :: [Symbol]) (cols :: [Type]) :: [Type] where+type family+    GroupKeyColumns (keys :: [Symbol]) (cols :: [(Symbol, Type)]) ::+        [(Symbol, Type)]+    where     GroupKeyColumns keys '[] = '[]-    GroupKeyColumns keys (Column n a ': rest) =+    GroupKeyColumns keys ('(n, a) ': rest) =         GroupKeyColumnsHelper (IsElem n keys) n a keys rest  type family@@ -554,15 +613,15 @@         (n :: Symbol)         (a :: Type)         (keys :: [Symbol])-        (rest :: [Type]) ::-        [Type]+        (rest :: [(Symbol, Type)]) ::+        [(Symbol, Type)]     where     GroupKeyColumnsHelper 'True n a keys rest =-        Column n a ': GroupKeyColumns keys rest+        '(n, a) ': GroupKeyColumns keys rest     GroupKeyColumnsHelper 'False n a keys rest = GroupKeyColumns keys rest  -- | Provides runtime evidence of a schema: a list of (name, TypeRep) pairs.-class KnownSchema (cols :: [Type]) where+class KnownSchema (cols :: [(Symbol, Type)]) where     schemaEvidence :: [(T.Text, SomeTypeRep)]  instance KnownSchema '[] where@@ -570,7 +629,7 @@  instance     (KnownSymbol name, Typeable a, Columnable a, KnownSchema rest) =>-    KnownSchema (Column name a ': rest)+    KnownSchema ('(name, a) ': rest)     where     schemaEvidence =         (T.pack (symbolVal (Proxy @name)), someTypeRep (Proxy @a))
src/DataFrame/Typed/Types.hs view
@@ -14,9 +14,6 @@     -- * Core phantom-typed wrapper     TypedDataFrame (..), -    -- * Column phantom type (no constructors)-    Column,-     -- * Typed expressions (schema-validated)     TExpr (..), @@ -49,11 +46,11 @@  {- | A phantom-typed wrapper over the untyped 'DataFrame'. -The type parameter @cols@ is a type-level list of @Column name ty@ entries+The type parameter @cols@ is a type-level list of @'(name, ty)@ pairs that tracks the schema at compile time. All operations delegate to the untyped core at runtime and update the phantom type at compile time. -}-newtype TypedDataFrame (cols :: [Type]) = TDF {unTDF :: D.DataFrame}+newtype TypedDataFrame (cols :: [(Symbol, Type)]) = TDF {unTDF :: D.DataFrame}  instance Show (TypedDataFrame cols) where     show (TDF df) = show df@@ -61,12 +58,6 @@ instance Eq (TypedDataFrame cols) where     (TDF a) == (TDF b) = a == b -{- | A phantom type that pairs a type-level column name ('Symbol')-with its element type. Has no value-level constructors — used-purely at the type level to describe schemas.--}-data Column (name :: Symbol) (a :: Type)- {- | A typed expression validated against schema @cols@, producing values of type @a@.  Unlike the untyped 'Expr a', a 'TExpr' can only be constructed through@@ -75,7 +66,7 @@  Use 'unTExpr' to extract the underlying 'Expr' for delegation to the untyped API. -}-newtype TExpr (cols :: [Type]) a = TExpr {unTExpr :: Expr a}+newtype TExpr (cols :: [(Symbol, Type)]) a = TExpr {unTExpr :: Expr a}  -- | Shows the underlying expression; the schema phantom is type-level only. instance (Show a) => Show (TExpr cols a) where@@ -85,23 +76,23 @@ @AsTExpr cols (Expr r) = TExpr cols r@. Lets a result type follow the frame — an @Expr@ over a plain frame becomes a @TExpr@ over a typed one. -}-type family AsTExpr (cols :: [Type]) (e :: Type) :: Type where+type family AsTExpr (cols :: [(Symbol, Type)]) (e :: Type) :: Type where     AsTExpr cols (Expr r) = TExpr cols r  -- | Lift an untyped expression into its 'TExpr' for schema @cols@.-class ToTExpr (cols :: [Type]) e where+class ToTExpr (cols :: [(Symbol, Type)]) e where     toTExpr :: e -> AsTExpr cols e  instance ToTExpr cols (Expr r) where     toTExpr = TExpr  -- | A typed sort order validated against schema @cols@.-data TSortOrder (cols :: [Type]) where+data TSortOrder (cols :: [(Symbol, Type)]) where     Asc :: (Columnable a, Ord a) => TExpr cols a -> TSortOrder cols     Desc :: (Columnable a, Ord a) => TExpr cols a -> TSortOrder cols  -- | A phantom-typed wrapper over 'GroupedDataFrame'.-newtype TypedGrouped (keys :: [Symbol]) (cols :: [Type])+newtype TypedGrouped (keys :: [Symbol]) (cols :: [(Symbol, Type)])     = TGD {unTGD :: D.GroupedDataFrame}  {- | Internal aggregation chain. Each cons prepends a 'Column' to the@@ -115,7 +106,7 @@   . as \@\"avg_age\" (F.mean age) @ -}-data TAgg (keys :: [Symbol]) (cols :: [Type]) (aggs :: [Type]) where+data TAgg (keys :: [Symbol]) (cols :: [(Symbol, Type)]) (aggs :: [(Symbol, Type)]) where     TAggNil :: TAgg keys cols '[]     TAggCons ::         (Columnable a) =>@@ -125,7 +116,7 @@         TExpr cols a ->         -- | rest         TAgg keys cols aggs ->-        TAgg keys cols (Column name a ': aggs)+        TAgg keys cols ('(name, a) ': aggs)  {- | Extract the runtime 'NamedExpr' list from a 'TAgg', in declaration order (reversed from the cons-built order).