{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE ScopedTypeVariables #-}

{- | Typed counterparts of the remaining "DataFrame.Functions" expression
combinators not already provided by "DataFrame.Typed.Expr". Each wraps the
untyped combinator 1:1, replacing @Expr@ with @'TExpr' cols@ so column
references stay schema-checked. Re-exported from "DataFrame.Typed.Expr".
-}
module DataFrame.Typed.Expr.Extra (
    div,
    mod,
    mode,
    sumMaybe,
    meanMaybe,
    variance,
    medianMaybe,
    percentile,
    stddev,
    stddevMaybe,
    zScore,
    pow,
    relu,
    min,
    max,
    reduce,
    toMaybe,
    fromMaybe,
    isJust,
    isNothing,
    fromJust,
    whenPresent,
    whenBothPresent,
    recode,
    recodeWithCondition,
    recodeWithDefault,
    firstOrNothing,
    lastOrNothing,
    splitOn,
    match,
    matchAll,
    parseDate,
    daysBetween,
    bind,
) where

import qualified Data.Text as T
import Data.Time (Day, ParseTime)
import qualified Data.Vector.Unboxed as VU
import Prelude hiding (div, max, min, mod)

import qualified DataFrame.Functions as F
import DataFrame.Internal.Column (Columnable)
import DataFrame.Typed.Types (TExpr (..))

-- | Integer division.
div ::
    (Integral a, Columnable a) => TExpr cols a -> TExpr cols a -> TExpr cols a
div :: forall a (cols :: [(Symbol, *)]).
(Integral a, Columnable a) =>
TExpr cols a -> TExpr cols a -> TExpr cols a
div (TExpr Expr a
a) (TExpr Expr a
b) = Expr a -> TExpr cols a
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr a -> Expr a -> Expr a
forall a. (Integral a, Columnable a) => Expr a -> Expr a -> Expr a
F.div Expr a
a Expr a
b)

-- | Integer modulus.
mod ::
    (Integral a, Columnable a) => TExpr cols a -> TExpr cols a -> TExpr cols a
mod :: forall a (cols :: [(Symbol, *)]).
(Integral a, Columnable a) =>
TExpr cols a -> TExpr cols a -> TExpr cols a
mod (TExpr Expr a
a) (TExpr Expr a
b) = Expr a -> TExpr cols a
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr a -> Expr a -> Expr a
forall a. (Integral a, Columnable a) => Expr a -> Expr a -> Expr a
F.mod Expr a
a Expr a
b)

-- | Most frequent value (aggregation).
mode :: (Ord a, Columnable a, Eq a) => TExpr cols a -> TExpr cols a
mode :: forall a (cols :: [(Symbol, *)]).
(Ord a, Columnable a, Eq a) =>
TExpr cols a -> TExpr cols a
mode (TExpr Expr a
e) = Expr a -> TExpr cols a
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr a -> Expr a
forall a. (Ord a, Columnable a, Eq a) => Expr a -> Expr a
F.mode Expr a
e)

-- | Sum of a nullable column, ignoring 'Nothing' (aggregation).
sumMaybe :: (Columnable a, Num a) => TExpr cols (Maybe a) -> TExpr cols a
sumMaybe :: forall a (cols :: [(Symbol, *)]).
(Columnable a, Num a) =>
TExpr cols (Maybe a) -> TExpr cols a
sumMaybe (TExpr Expr (Maybe a)
e) = Expr a -> TExpr cols a
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr (Maybe a) -> Expr a
forall a. (Columnable a, Num a) => Expr (Maybe a) -> Expr a
F.sumMaybe Expr (Maybe a)
e)

-- | Mean of a nullable column, ignoring 'Nothing' (aggregation).
meanMaybe :: (Columnable a, Real a) => TExpr cols (Maybe a) -> TExpr cols Double
meanMaybe :: forall a (cols :: [(Symbol, *)]).
(Columnable a, Real a) =>
TExpr cols (Maybe a) -> TExpr cols Double
meanMaybe (TExpr Expr (Maybe a)
e) = Expr Double -> TExpr cols Double
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr (Maybe a) -> Expr Double
forall a. (Columnable a, Real a) => Expr (Maybe a) -> Expr Double
F.meanMaybe Expr (Maybe a)
e)

-- | Variance (aggregation).
variance ::
    (Columnable a, Real a, VU.Unbox a) => TExpr cols a -> TExpr cols Double
variance :: forall a (cols :: [(Symbol, *)]).
(Columnable a, Real a, Unbox a) =>
TExpr cols a -> TExpr cols Double
variance (TExpr Expr a
e) = Expr Double -> TExpr cols Double
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr a -> Expr Double
forall a. (Columnable a, Real a, Unbox a) => Expr a -> Expr Double
F.variance Expr a
e)

-- | Median of a nullable column, ignoring 'Nothing' (aggregation).
medianMaybe ::
    (Columnable a, Real a) => TExpr cols (Maybe a) -> TExpr cols Double
medianMaybe :: forall a (cols :: [(Symbol, *)]).
(Columnable a, Real a) =>
TExpr cols (Maybe a) -> TExpr cols Double
medianMaybe (TExpr Expr (Maybe a)
e) = Expr Double -> TExpr cols Double
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr (Maybe a) -> Expr Double
forall a. (Columnable a, Real a) => Expr (Maybe a) -> Expr Double
F.medianMaybe Expr (Maybe a)
e)

-- | The @n@-th percentile (aggregation).
percentile :: Int -> TExpr cols Double -> TExpr cols Double
percentile :: forall (cols :: [(Symbol, *)]).
Int -> TExpr cols Double -> TExpr cols Double
percentile Int
n (TExpr Expr Double
e) = Expr Double -> TExpr cols Double
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Int -> Expr Double -> Expr Double
F.percentile Int
n Expr Double
e)

-- | Standard deviation (aggregation).
stddev ::
    (Columnable a, Real a, VU.Unbox a) => TExpr cols a -> TExpr cols Double
stddev :: forall a (cols :: [(Symbol, *)]).
(Columnable a, Real a, Unbox a) =>
TExpr cols a -> TExpr cols Double
stddev (TExpr Expr a
e) = Expr Double -> TExpr cols Double
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr a -> Expr Double
forall a. (Columnable a, Real a, Unbox a) => Expr a -> Expr Double
F.stddev Expr a
e)

-- | Standard deviation of a nullable column, ignoring 'Nothing' (aggregation).
stddevMaybe ::
    (Columnable a, Real a) => TExpr cols (Maybe a) -> TExpr cols Double
stddevMaybe :: forall a (cols :: [(Symbol, *)]).
(Columnable a, Real a) =>
TExpr cols (Maybe a) -> TExpr cols Double
stddevMaybe (TExpr Expr (Maybe a)
e) = Expr Double -> TExpr cols Double
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr (Maybe a) -> Expr Double
forall a. (Columnable a, Real a) => Expr (Maybe a) -> Expr Double
F.stddevMaybe Expr (Maybe a)
e)

-- | Z-score (value minus group mean, over standard deviation).
zScore :: TExpr cols Double -> TExpr cols Double
zScore :: forall (cols :: [(Symbol, *)]).
TExpr cols Double -> TExpr cols Double
zScore (TExpr Expr Double
e) = Expr Double -> TExpr cols Double
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr Double -> Expr Double
F.zScore Expr Double
e)

-- | Raise an expression to an integer power.
pow :: (Columnable a, Num a) => TExpr cols a -> Int -> TExpr cols a
pow :: forall a (cols :: [(Symbol, *)]).
(Columnable a, Num a) =>
TExpr cols a -> Int -> TExpr cols a
pow (TExpr Expr a
e) Int
i = Expr a -> TExpr cols a
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr a -> Int -> Expr a
forall a. (Columnable a, Num a) => Expr a -> Int -> Expr a
F.pow Expr a
e Int
i)

-- | Rectified linear unit: @max 0@.
relu :: (Columnable a, Num a, Ord a) => TExpr cols a -> TExpr cols a
relu :: forall a (cols :: [(Symbol, *)]).
(Columnable a, Num a, Ord a) =>
TExpr cols a -> TExpr cols a
relu (TExpr Expr a
e) = Expr a -> TExpr cols a
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr a -> Expr a
forall a. (Columnable a, Num a, Ord a) => Expr a -> Expr a
F.relu Expr a
e)

-- | Element-wise minimum of two expressions.
min :: (Columnable a, Ord a) => TExpr cols a -> TExpr cols a -> TExpr cols a
min :: forall a (cols :: [(Symbol, *)]).
(Columnable a, Ord a) =>
TExpr cols a -> TExpr cols a -> TExpr cols a
min (TExpr Expr a
a) (TExpr Expr a
b) = Expr a -> TExpr cols a
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr a -> Expr a -> Expr a
forall a. (Columnable a, Ord a) => Expr a -> Expr a -> Expr a
F.min Expr a
a Expr a
b)

-- | Element-wise maximum of two expressions.
max :: (Columnable a, Ord a) => TExpr cols a -> TExpr cols a -> TExpr cols a
max :: forall a (cols :: [(Symbol, *)]).
(Columnable a, Ord a) =>
TExpr cols a -> TExpr cols a -> TExpr cols a
max (TExpr Expr a
a) (TExpr Expr a
b) = Expr a -> TExpr cols a
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr a -> Expr a -> Expr a
forall a. (Columnable a, Ord a) => Expr a -> Expr a -> Expr a
F.max Expr a
a Expr a
b)

-- | Fold a column into a single value with a seed and step function (aggregation).
reduce ::
    (Columnable a, Columnable b) =>
    TExpr cols b -> a -> (a -> b -> a) -> TExpr cols a
reduce :: forall a b (cols :: [(Symbol, *)]).
(Columnable a, Columnable b) =>
TExpr cols b -> a -> (a -> b -> a) -> TExpr cols a
reduce (TExpr Expr b
e) a
start a -> b -> a
f = Expr a -> TExpr cols a
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr b -> a -> (a -> b -> a) -> Expr a
forall a b.
(Columnable a, Columnable b) =>
Expr b -> a -> (a -> b -> a) -> Expr a
F.reduce Expr b
e a
start a -> b -> a
f)

-- | Wrap each value in 'Just'.
toMaybe :: (Columnable a) => TExpr cols a -> TExpr cols (Maybe a)
toMaybe :: forall a (cols :: [(Symbol, *)]).
Columnable a =>
TExpr cols a -> TExpr cols (Maybe a)
toMaybe (TExpr Expr a
e) = Expr (Maybe a) -> TExpr cols (Maybe a)
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr a -> Expr (Maybe a)
forall a. Columnable a => Expr a -> Expr (Maybe a)
F.toMaybe Expr a
e)

-- | Replace 'Nothing' with a default.
fromMaybe :: (Columnable a) => a -> TExpr cols (Maybe a) -> TExpr cols a
fromMaybe :: forall a (cols :: [(Symbol, *)]).
Columnable a =>
a -> TExpr cols (Maybe a) -> TExpr cols a
fromMaybe a
d (TExpr Expr (Maybe a)
e) = Expr a -> TExpr cols a
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (a -> Expr (Maybe a) -> Expr a
forall a. Columnable a => a -> Expr (Maybe a) -> Expr a
F.fromMaybe a
d Expr (Maybe a)
e)

-- | True where the value is 'Just'.
isJust :: (Columnable a) => TExpr cols (Maybe a) -> TExpr cols Bool
isJust :: forall a (cols :: [(Symbol, *)]).
Columnable a =>
TExpr cols (Maybe a) -> TExpr cols Bool
isJust (TExpr Expr (Maybe a)
e) = Expr Bool -> TExpr cols Bool
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr (Maybe a) -> Expr Bool
forall a. Columnable a => Expr (Maybe a) -> Expr Bool
F.isJust Expr (Maybe a)
e)

-- | True where the value is 'Nothing'.
isNothing :: (Columnable a) => TExpr cols (Maybe a) -> TExpr cols Bool
isNothing :: forall a (cols :: [(Symbol, *)]).
Columnable a =>
TExpr cols (Maybe a) -> TExpr cols Bool
isNothing (TExpr Expr (Maybe a)
e) = Expr Bool -> TExpr cols Bool
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr (Maybe a) -> Expr Bool
forall a. Columnable a => Expr (Maybe a) -> Expr Bool
F.isNothing Expr (Maybe a)
e)

-- | Unwrap a 'Just', erroring on 'Nothing'.
fromJust :: (Columnable a) => TExpr cols (Maybe a) -> TExpr cols a
fromJust :: forall a (cols :: [(Symbol, *)]).
Columnable a =>
TExpr cols (Maybe a) -> TExpr cols a
fromJust (TExpr Expr (Maybe a)
e) = Expr a -> TExpr cols a
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr (Maybe a) -> Expr a
forall a. Columnable a => Expr (Maybe a) -> Expr a
F.fromJust Expr (Maybe a)
e)

-- | Apply a function only where the value is present.
whenPresent ::
    (Columnable a, Columnable b) =>
    (a -> b) -> TExpr cols (Maybe a) -> TExpr cols (Maybe b)
whenPresent :: forall a b (cols :: [(Symbol, *)]).
(Columnable a, Columnable b) =>
(a -> b) -> TExpr cols (Maybe a) -> TExpr cols (Maybe b)
whenPresent a -> b
f (TExpr Expr (Maybe a)
e) = Expr (Maybe b) -> TExpr cols (Maybe b)
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr ((a -> b) -> Expr (Maybe a) -> Expr (Maybe b)
forall a b.
(Columnable a, Columnable b) =>
(a -> b) -> Expr (Maybe a) -> Expr (Maybe b)
F.whenPresent a -> b
f Expr (Maybe a)
e)

-- | Apply a binary function only where both values are present.
whenBothPresent ::
    (Columnable a, Columnable b, Columnable c) =>
    (a -> b -> c) ->
    TExpr cols (Maybe a) ->
    TExpr cols (Maybe b) ->
    TExpr cols (Maybe c)
whenBothPresent :: forall a b c (cols :: [(Symbol, *)]).
(Columnable a, Columnable b, Columnable c) =>
(a -> b -> c)
-> TExpr cols (Maybe a)
-> TExpr cols (Maybe b)
-> TExpr cols (Maybe c)
whenBothPresent a -> b -> c
f (TExpr Expr (Maybe a)
a) (TExpr Expr (Maybe b)
b) = Expr (Maybe c) -> TExpr cols (Maybe c)
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr ((a -> b -> c) -> Expr (Maybe a) -> Expr (Maybe b) -> Expr (Maybe c)
forall a b c.
(Columnable a, Columnable b, Columnable c) =>
(a -> b -> c) -> Expr (Maybe a) -> Expr (Maybe b) -> Expr (Maybe c)
F.whenBothPresent a -> b -> c
f Expr (Maybe a)
a Expr (Maybe b)
b)

-- | Map values through a lookup table, yielding 'Nothing' for misses.
recode ::
    (Columnable a, Columnable b, Show a, Show b, Show (a, b)) =>
    [(a, b)] -> TExpr cols a -> TExpr cols (Maybe b)
recode :: forall a b (cols :: [(Symbol, *)]).
(Columnable a, Columnable b, Show a, Show b, Show (a, b)) =>
[(a, b)] -> TExpr cols a -> TExpr cols (Maybe b)
recode [(a, b)]
mapping (TExpr Expr a
e) = Expr (Maybe b) -> TExpr cols (Maybe b)
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr ([(a, b)] -> Expr a -> Expr (Maybe b)
forall a b.
(Columnable a, Columnable b, Show (a, b)) =>
[(a, b)] -> Expr a -> Expr (Maybe b)
F.recode [(a, b)]
mapping Expr a
e)

-- | Pick the first value whose condition holds, else a fallback.
recodeWithCondition ::
    (Columnable a, Columnable b) =>
    TExpr cols b ->
    [(TExpr cols a -> TExpr cols Bool, b)] ->
    TExpr cols a ->
    TExpr cols b
recodeWithCondition :: forall a b (cols :: [(Symbol, *)]).
(Columnable a, Columnable b) =>
TExpr cols b
-> [(TExpr cols a -> TExpr cols Bool, b)]
-> TExpr cols a
-> TExpr cols b
recodeWithCondition (TExpr Expr b
fallback) [(TExpr cols a -> TExpr cols Bool, b)]
conds (TExpr Expr a
e) =
    Expr b -> TExpr cols b
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr b -> [(Expr a -> Expr Bool, b)] -> Expr a -> Expr b
forall a b.
(Columnable a, Columnable b) =>
Expr b -> [(Expr a -> Expr Bool, b)] -> Expr a -> Expr b
F.recodeWithCondition Expr b
fallback (((TExpr cols a -> TExpr cols Bool, b) -> (Expr a -> Expr Bool, b))
-> [(TExpr cols a -> TExpr cols Bool, b)]
-> [(Expr a -> Expr Bool, b)]
forall a b. (a -> b) -> [a] -> [b]
map (TExpr cols a -> TExpr cols Bool, b) -> (Expr a -> Expr Bool, b)
forall {cols :: [(Symbol, *)]} {a} {cols :: [(Symbol, *)]} {a} {b}.
(TExpr cols a -> TExpr cols a, b) -> (Expr a -> Expr a, b)
untype [(TExpr cols a -> TExpr cols Bool, b)]
conds) Expr a
e)
  where
    untype :: (TExpr cols a -> TExpr cols a, b) -> (Expr a -> Expr a, b)
untype (TExpr cols a -> TExpr cols a
p, b
v) = (TExpr cols a -> Expr a
forall (cols :: [(Symbol, *)]) a. TExpr cols a -> Expr a
unTExpr (TExpr cols a -> Expr a)
-> (Expr a -> TExpr cols a) -> Expr a -> Expr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TExpr cols a -> TExpr cols a
p (TExpr cols a -> TExpr cols a)
-> (Expr a -> TExpr cols a) -> Expr a -> TExpr cols a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr a -> TExpr cols a
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr, b
v)

-- | Map values through a lookup table, with a default for misses.
recodeWithDefault ::
    (Columnable a, Columnable b, Show (a, b)) =>
    b -> [(a, b)] -> TExpr cols a -> TExpr cols b
recodeWithDefault :: forall a b (cols :: [(Symbol, *)]).
(Columnable a, Columnable b, Show (a, b)) =>
b -> [(a, b)] -> TExpr cols a -> TExpr cols b
recodeWithDefault b
d [(a, b)]
mapping (TExpr Expr a
e) = Expr b -> TExpr cols b
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (b -> [(a, b)] -> Expr a -> Expr b
forall a b.
(Columnable a, Columnable b, Show (a, b)) =>
b -> [(a, b)] -> Expr a -> Expr b
F.recodeWithDefault b
d [(a, b)]
mapping Expr a
e)

-- | First element of a list column, or 'Nothing'.
firstOrNothing :: (Columnable a) => TExpr cols [a] -> TExpr cols (Maybe a)
firstOrNothing :: forall a (cols :: [(Symbol, *)]).
Columnable a =>
TExpr cols [a] -> TExpr cols (Maybe a)
firstOrNothing (TExpr Expr [a]
e) = Expr (Maybe a) -> TExpr cols (Maybe a)
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr [a] -> Expr (Maybe a)
forall a. Columnable a => Expr [a] -> Expr (Maybe a)
F.firstOrNothing Expr [a]
e)

-- | Last element of a list column, or 'Nothing'.
lastOrNothing :: (Columnable a) => TExpr cols [a] -> TExpr cols (Maybe a)
lastOrNothing :: forall a (cols :: [(Symbol, *)]).
Columnable a =>
TExpr cols [a] -> TExpr cols (Maybe a)
lastOrNothing (TExpr Expr [a]
e) = Expr (Maybe a) -> TExpr cols (Maybe a)
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr [a] -> Expr (Maybe a)
forall a. Columnable a => Expr [a] -> Expr (Maybe a)
F.lastOrNothing Expr [a]
e)

-- | Split text on a delimiter.
splitOn :: T.Text -> TExpr cols T.Text -> TExpr cols [T.Text]
splitOn :: forall (cols :: [(Symbol, *)]).
Text -> TExpr cols Text -> TExpr cols [Text]
splitOn Text
delim (TExpr Expr Text
e) = Expr [Text] -> TExpr cols [Text]
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Text -> Expr Text -> Expr [Text]
F.splitOn Text
delim Expr Text
e)

-- | First regex match, or 'Nothing'.
match :: T.Text -> TExpr cols T.Text -> TExpr cols (Maybe T.Text)
match :: forall (cols :: [(Symbol, *)]).
Text -> TExpr cols Text -> TExpr cols (Maybe Text)
match Text
regex (TExpr Expr Text
e) = Expr (Maybe Text) -> TExpr cols (Maybe Text)
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Text -> Expr Text -> Expr (Maybe Text)
F.match Text
regex Expr Text
e)

-- | All regex matches.
matchAll :: T.Text -> TExpr cols T.Text -> TExpr cols [T.Text]
matchAll :: forall (cols :: [(Symbol, *)]).
Text -> TExpr cols Text -> TExpr cols [Text]
matchAll Text
regex (TExpr Expr Text
e) = Expr [Text] -> TExpr cols [Text]
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Text -> Expr Text -> Expr [Text]
F.matchAll Text
regex Expr Text
e)

-- | Parse text into a time value with the given format.
parseDate ::
    (ParseTime t, Columnable t) =>
    T.Text -> TExpr cols T.Text -> TExpr cols (Maybe t)
parseDate :: forall t (cols :: [(Symbol, *)]).
(ParseTime t, Columnable t) =>
Text -> TExpr cols Text -> TExpr cols (Maybe t)
parseDate Text
format (TExpr Expr Text
e) = Expr (Maybe t) -> TExpr cols (Maybe t)
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Text -> Expr Text -> Expr (Maybe t)
forall t.
(ParseTime t, Columnable t) =>
Text -> Expr Text -> Expr (Maybe t)
F.parseDate Text
format Expr Text
e)

-- | Number of days between two dates.
daysBetween :: TExpr cols Day -> TExpr cols Day -> TExpr cols Int
daysBetween :: forall (cols :: [(Symbol, *)]).
TExpr cols Day -> TExpr cols Day -> TExpr cols Int
daysBetween (TExpr Expr Day
a) (TExpr Expr Day
b) = Expr Int -> TExpr cols Int
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr (Expr Day -> Expr Day -> Expr Int
F.daysBetween Expr Day
a Expr Day
b)

-- | Monadic bind over a column of monadic values.
bind ::
    (Columnable a, Columnable (m a), Monad m, Columnable b, Columnable (m b)) =>
    (a -> m b) -> TExpr cols (m a) -> TExpr cols (m b)
bind :: forall a (m :: * -> *) b (cols :: [(Symbol, *)]).
(Columnable a, Columnable (m a), Monad m, Columnable b,
 Columnable (m b)) =>
(a -> m b) -> TExpr cols (m a) -> TExpr cols (m b)
bind a -> m b
f (TExpr Expr (m a)
e) = Expr (m b) -> TExpr cols (m b)
forall (cols :: [(Symbol, *)]) a. Expr a -> TExpr cols a
TExpr ((a -> m b) -> Expr (m a) -> Expr (m b)
forall a b (m :: * -> *).
(Columnable a, Columnable (m a), Monad m, Columnable b,
 Columnable (m b)) =>
(a -> m b) -> Expr (m a) -> Expr (m b)
F.bind a -> m b
f Expr (m a)
e)