dataframe-1.1.2.0: src/DataFrame/Typed.hs
{-# LANGUAGE DataKinds #-}
{- |
Module : DataFrame.Typed
Copyright : (c) 2025
License : MIT
Maintainer : mschavinda@gmail.com
Stability : experimental
A type-safe layer over the @dataframe@ library.
This module provides 'TypedDataFrame', a phantom-typed wrapper around
the untyped 'DataFrame' that tracks column names and types at compile time.
All operations delegate to the untyped core at runtime; the phantom type
is updated at compile time to reflect schema changes.
== Key difference from untyped API: TExpr
All expression-taking operations use 'TExpr' (typed expressions) instead
of raw @Expr@. Column references are validated at compile time:
@
{\-\# LANGUAGE DataKinds, TypeApplications, TypeOperators \#-\}
import qualified DataFrame.Typed as T
type People = '[T.Column \"name\" Text, T.Column \"age\" Int]
main = do
raw <- D.readCsv \"people.csv\"
case T.freeze \@People raw of
Nothing -> putStrLn \"Schema mismatch!\"
Just df -> do
let adults = T.filterWhere (T.col \@\"age\" T..>=. T.lit 18) df
let names = T.columnAsList \@\"name\" adults -- :: [Text]
print names
@
Column references like @T.col \@\"age\"@ are checked at compile time — if the
column doesn't exist or has the wrong type, you get a type error, not a
runtime exception.
== filterAllJust tracks Maybe-stripping
@
df :: TypedDataFrame '[Column \"x\" (Maybe Double), Column \"y\" Int]
T.filterAllJust df :: TypedDataFrame '[Column \"x\" Double, Column \"y\" Int]
@
== Typed aggregation (Option B)
@
result = T.aggregate
(T.agg \@\"total\" (T.tsum (T.col \@\"salary\"))
$ T.agg \@\"count\" (T.tcount (T.col \@\"salary\"))
$ T.aggNil)
(T.groupBy \@'[\"dept\"] employees)
@
-}
module DataFrame.Typed (
-- * Core types
TypedDataFrame,
Column,
TypedGrouped,
These (..),
-- * Typed expressions
TExpr (..),
col,
lit,
ifThenElse,
lift,
lift2,
nullLift,
nullLift2,
-- * Same-type comparison operators
(.==.),
(./=.),
(.<.),
(.<=.),
(.>=.),
(.>.),
-- * Nullable-aware arithmetic operators
(.+),
(.-),
(.*),
(./),
-- * Nullable-aware comparison operators (three-valued logic)
(.==),
(./=),
(.<),
(.<=),
(.>=),
(.>),
-- * Logical operators
(.&&.),
(.||.),
DataFrame.Typed.Expr.not,
-- * Aggregation expression combinators
DataFrame.Typed.Expr.sum,
mean,
count,
countAll,
DataFrame.Typed.Expr.minimum,
DataFrame.Typed.Expr.maximum,
collect,
-- * Typed sort orders
TSortOrder (..),
asc,
desc,
-- * Named expression helper
DataFrame.Typed.Expr.as,
-- * Freeze / thaw boundary
freeze,
freezeWithError,
thaw,
unsafeFreeze,
-- * Typed column access
columnAsVector,
columnAsList,
-- * Schema-preserving operations
filterWhere,
filter,
filterBy,
filterAllJust,
filterJust,
filterNothing,
sortBy,
take,
takeLast,
drop,
dropLast,
range,
cube,
distinct,
sample,
shuffle,
-- * Schema-modifying operations
derive,
impute,
select,
exclude,
rename,
renameMany,
insert,
insertColumn,
insertVector,
cloneColumn,
dropColumn,
replaceColumn,
-- * Metadata
dimensions,
nRows,
nColumns,
columnNames,
-- * Vertical merge
append,
-- * Joins
innerJoin,
leftJoin,
rightJoin,
fullOuterJoin,
-- * GroupBy and Aggregation (Option B)
groupBy,
agg,
aggNil,
aggregate,
aggregateUntyped,
-- * Template Haskell
deriveSchema,
deriveSchemaFromCsvFile,
deriveSchemaFromCsvFileWith,
-- * Schema type families (for advanced use)
Lookup,
SafeLookup,
HasName,
SubsetSchema,
ExcludeSchema,
RenameInSchema,
RenameManyInSchema,
RemoveColumn,
Impute,
Append,
Reverse,
StripAllMaybe,
StripMaybeAt,
GroupKeyColumns,
InnerJoinSchema,
LeftJoinSchema,
RightJoinSchema,
FullOuterJoinSchema,
AssertAbsent,
AssertAllPresent,
AssertPresent,
-- * Constraints
KnownSchema (..),
AllKnownSymbol (..),
) where
import Prelude hiding (drop, filter, take)
import DataFrame.Typed.Access (columnAsList, columnAsVector)
import DataFrame.Typed.Aggregate (
agg,
aggNil,
aggregate,
aggregateUntyped,
groupBy,
)
import DataFrame.Typed.Expr
import DataFrame.Typed.Freeze (freeze, freezeWithError, thaw, unsafeFreeze)
import DataFrame.Typed.Join (fullOuterJoin, innerJoin, leftJoin, rightJoin)
import DataFrame.Typed.Operations
import DataFrame.Typed.Schema
import DataFrame.Typed.TH (
deriveSchema,
deriveSchemaFromCsvFile,
deriveSchemaFromCsvFileWith,
)
import DataFrame.Typed.Types (
Column,
TSortOrder (..),
These (..),
TypedDataFrame,
TypedGrouped,
)