{-# language DeriveTraversable #-}
{-# language GeneralizedNewtypeDeriving #-}
{-# language LambdaCase #-}
{-# language RankNTypes #-}
{-# options_ghc -Wno-unused-imports #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Heidi.Data.Row.GenericTrie
-- Description :  A sparse dataframe row, based on GenericTrie
-- Copyright   :  (c) Marco Zocca (2018-2019)
-- License     :  BSD-style
-- Maintainer  :  ocramz fripost org
-- Stability   :  experimental
-- Portability :  GHC
--
-- Rows are internally represented with prefix trees ("tries"), as provided by the
-- @generic-trie@ library; in addition to supporting the possibility of missing features in the dataset, tries provide fast insertion and lookup functionality when keyed with structured datatypes (such as lists or trees).
--
-----------------------------------------------------------------------------
module Heidi.Data.Row.GenericTrie (
    Row
    -- * Construction
  , rowFromList, empty
  -- ** (unsafe)
  , mkRow
  -- * Update
  , insert, insertMany, insertWith
  -- * Access
  , toList, keys
  -- * Filtering
  , delete, filterWithKey, filterWithKeyPrefix, filterWithKeyAny
  , deleteMany
  -- * Partitioning
  , partitionWithKey, partitionWithKeyPrefix
  -- -- ** Decoders
  -- , real, scientific, text, string, oneHot
  -- * Lookup
  , lookup
  -- , lookupThrowM
  , (!:), elemSatisfies
  -- ** Lookup utilities
  , maybeEmpty
  -- ** Comparison by lookup
  , eqByLookup, eqByLookups
  , compareByLookup
  -- * Set operations
  , union, unionWith
  , intersection, intersectionWith
  -- * Maps
  , mapWithKey
  -- * Folds
  , foldWithKey, keysOnly
  -- * Traversals
  , traverseWithKey
  -- * Lens combinators
  -- ** Traversals
  , int, bool, float, double, char, string, text, scientific, oneHot
  -- ** Getters
  , real, txt
  -- , flag
  -- ** Combinators
  , at, keep
  -- *** Combinators for list-indexed rows
  , atPrefix, eachPrefixed, foldPrefixed
  ) where

import qualified Control.Applicative as A (empty)
import Control.Applicative ((<|>))
import Data.Functor.Const (Const(..))
import Data.Functor.Identity (Identity(..))
import Data.List (isPrefixOf)
import Data.Maybe (fromMaybe)
import Data.Monoid (Any(..), All(..), First(..))
-- import Data.Semigroup (Endo)
-- import Data.Typeable (Typeable)
-- import Control.Applicative (Alternative(..))
import qualified Data.Foldable as F
-- import Control.Monad (filterM)
-- generic-trie
import qualified Data.GenericTrie as GT
-- exceptions
-- import Control.Monad.Catch (MonadThrow(..))
-- microlens
import Lens.Micro (Lens', Traversal', Getting, (^.), (^?), (<&>), _Just, Getting, traversed, folded, to, has, (.~), failing)
-- -- microlens-th
-- import Lens.Micro.TH (makeLenses)
-- scientific
import Data.Scientific (Scientific)
-- text
import Data.Text (Text)
import qualified Data.Text as T (pack, unpack)


-- import qualified Data.Generics.Decode as D (Decode, mkDecode)
-- import Data.Generics.Decode ((>>>))
import Data.Generics.Encode.Internal (VP, vpInt, vpFloat, vpDouble, vpString, vpChar, vpText, vpBool, vpScientific, vpOneHot)
import Data.Generics.Encode.OneHot (OneHot)
-- import Data.Generics.Codec
-- import Core.Data.Row.Internal (KeyError(..))

import Prelude hiding (any, lookup)


-- $setup
-- >>> import Data.Generics.Encode.Internal (VP)
-- >>> let row0 = fromList [(0, 'a'), (3, 'b')] :: Row Int Char
-- >>> let row1 = fromList [(0, 'x'), (1, 'b'), (666, 'z')] :: Row Int Char


-- | A 'Row' type is internally a Trie:
--
-- * Fast random access
-- * Fast set operations
-- * Supports missing elements
newtype Row k v = Row { Row k v -> Trie k v
_unRow :: GT.Trie k v } deriving (a -> Row k b -> Row k a
(a -> b) -> Row k a -> Row k b
(forall a b. (a -> b) -> Row k a -> Row k b)
-> (forall a b. a -> Row k b -> Row k a) -> Functor (Row k)
forall k a b. TrieKey k => a -> Row k b -> Row k a
forall k a b. TrieKey k => (a -> b) -> Row k a -> Row k b
forall a b. a -> Row k b -> Row k a
forall a b. (a -> b) -> Row k a -> Row k b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Row k b -> Row k a
$c<$ :: forall k a b. TrieKey k => a -> Row k b -> Row k a
fmap :: (a -> b) -> Row k a -> Row k b
$cfmap :: forall k a b. TrieKey k => (a -> b) -> Row k a -> Row k b
Functor, a -> Row k a -> Bool
Row k m -> m
Row k a -> [a]
Row k a -> Bool
Row k a -> Int
Row k a -> a
Row k a -> a
Row k a -> a
Row k a -> a
(a -> m) -> Row k a -> m
(a -> m) -> Row k a -> m
(a -> b -> b) -> b -> Row k a -> b
(a -> b -> b) -> b -> Row k a -> b
(b -> a -> b) -> b -> Row k a -> b
(b -> a -> b) -> b -> Row k a -> b
(a -> a -> a) -> Row k a -> a
(a -> a -> a) -> Row k a -> a
(forall m. Monoid m => Row k m -> m)
-> (forall m a. Monoid m => (a -> m) -> Row k a -> m)
-> (forall m a. Monoid m => (a -> m) -> Row k a -> m)
-> (forall a b. (a -> b -> b) -> b -> Row k a -> b)
-> (forall a b. (a -> b -> b) -> b -> Row k a -> b)
-> (forall b a. (b -> a -> b) -> b -> Row k a -> b)
-> (forall b a. (b -> a -> b) -> b -> Row k a -> b)
-> (forall a. (a -> a -> a) -> Row k a -> a)
-> (forall a. (a -> a -> a) -> Row k a -> a)
-> (forall a. Row k a -> [a])
-> (forall a. Row k a -> Bool)
-> (forall a. Row k a -> Int)
-> (forall a. Eq a => a -> Row k a -> Bool)
-> (forall a. Ord a => Row k a -> a)
-> (forall a. Ord a => Row k a -> a)
-> (forall a. Num a => Row k a -> a)
-> (forall a. Num a => Row k a -> a)
-> Foldable (Row k)
forall a. Eq a => a -> Row k a -> Bool
forall a. Num a => Row k a -> a
forall a. Ord a => Row k a -> a
forall m. Monoid m => Row k m -> m
forall k a. (TrieKey k, Eq a) => a -> Row k a -> Bool
forall k a. (TrieKey k, Num a) => Row k a -> a
forall k a. (TrieKey k, Ord a) => Row k a -> a
forall k m. (TrieKey k, Monoid m) => Row k m -> m
forall k a. TrieKey k => Row k a -> Bool
forall k a. TrieKey k => Row k a -> Int
forall k a. TrieKey k => Row k a -> [a]
forall k a. TrieKey k => (a -> a -> a) -> Row k a -> a
forall k m a. (TrieKey k, Monoid m) => (a -> m) -> Row k a -> m
forall k b a. TrieKey k => (b -> a -> b) -> b -> Row k a -> b
forall k a b. TrieKey k => (a -> b -> b) -> b -> Row k a -> b
forall a. Row k a -> Bool
forall a. Row k a -> Int
forall a. Row k a -> [a]
forall a. (a -> a -> a) -> Row k a -> a
forall m a. Monoid m => (a -> m) -> Row k a -> m
forall b a. (b -> a -> b) -> b -> Row k a -> b
forall a b. (a -> b -> b) -> b -> Row k a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: Row k a -> a
$cproduct :: forall k a. (TrieKey k, Num a) => Row k a -> a
sum :: Row k a -> a
$csum :: forall k a. (TrieKey k, Num a) => Row k a -> a
minimum :: Row k a -> a
$cminimum :: forall k a. (TrieKey k, Ord a) => Row k a -> a
maximum :: Row k a -> a
$cmaximum :: forall k a. (TrieKey k, Ord a) => Row k a -> a
elem :: a -> Row k a -> Bool
$celem :: forall k a. (TrieKey k, Eq a) => a -> Row k a -> Bool
length :: Row k a -> Int
$clength :: forall k a. TrieKey k => Row k a -> Int
null :: Row k a -> Bool
$cnull :: forall k a. TrieKey k => Row k a -> Bool
toList :: Row k a -> [a]
$ctoList :: forall k a. TrieKey k => Row k a -> [a]
foldl1 :: (a -> a -> a) -> Row k a -> a
$cfoldl1 :: forall k a. TrieKey k => (a -> a -> a) -> Row k a -> a
foldr1 :: (a -> a -> a) -> Row k a -> a
$cfoldr1 :: forall k a. TrieKey k => (a -> a -> a) -> Row k a -> a
foldl' :: (b -> a -> b) -> b -> Row k a -> b
$cfoldl' :: forall k b a. TrieKey k => (b -> a -> b) -> b -> Row k a -> b
foldl :: (b -> a -> b) -> b -> Row k a -> b
$cfoldl :: forall k b a. TrieKey k => (b -> a -> b) -> b -> Row k a -> b
foldr' :: (a -> b -> b) -> b -> Row k a -> b
$cfoldr' :: forall k a b. TrieKey k => (a -> b -> b) -> b -> Row k a -> b
foldr :: (a -> b -> b) -> b -> Row k a -> b
$cfoldr :: forall k a b. TrieKey k => (a -> b -> b) -> b -> Row k a -> b
foldMap' :: (a -> m) -> Row k a -> m
$cfoldMap' :: forall k m a. (TrieKey k, Monoid m) => (a -> m) -> Row k a -> m
foldMap :: (a -> m) -> Row k a -> m
$cfoldMap :: forall k m a. (TrieKey k, Monoid m) => (a -> m) -> Row k a -> m
fold :: Row k m -> m
$cfold :: forall k m. (TrieKey k, Monoid m) => Row k m -> m
Foldable, Functor (Row k)
Foldable (Row k)
Functor (Row k)
-> Foldable (Row k)
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Row k a -> f (Row k b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Row k (f a) -> f (Row k a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Row k a -> m (Row k b))
-> (forall (m :: * -> *) a. Monad m => Row k (m a) -> m (Row k a))
-> Traversable (Row k)
(a -> f b) -> Row k a -> f (Row k b)
forall k. TrieKey k => Functor (Row k)
forall k. TrieKey k => Foldable (Row k)
forall k (m :: * -> *) a.
(TrieKey k, Monad m) =>
Row k (m a) -> m (Row k a)
forall k (f :: * -> *) a.
(TrieKey k, Applicative f) =>
Row k (f a) -> f (Row k a)
forall k (m :: * -> *) a b.
(TrieKey k, Monad m) =>
(a -> m b) -> Row k a -> m (Row k b)
forall k (f :: * -> *) a b.
(TrieKey k, Applicative f) =>
(a -> f b) -> Row k a -> f (Row k b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Row k (m a) -> m (Row k a)
forall (f :: * -> *) a. Applicative f => Row k (f a) -> f (Row k a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Row k a -> m (Row k b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Row k a -> f (Row k b)
sequence :: Row k (m a) -> m (Row k a)
$csequence :: forall k (m :: * -> *) a.
(TrieKey k, Monad m) =>
Row k (m a) -> m (Row k a)
mapM :: (a -> m b) -> Row k a -> m (Row k b)
$cmapM :: forall k (m :: * -> *) a b.
(TrieKey k, Monad m) =>
(a -> m b) -> Row k a -> m (Row k b)
sequenceA :: Row k (f a) -> f (Row k a)
$csequenceA :: forall k (f :: * -> *) a.
(TrieKey k, Applicative f) =>
Row k (f a) -> f (Row k a)
traverse :: (a -> f b) -> Row k a -> f (Row k b)
$ctraverse :: forall k (f :: * -> *) a b.
(TrieKey k, Applicative f) =>
(a -> f b) -> Row k a -> f (Row k b)
$cp2Traversable :: forall k. TrieKey k => Foldable (Row k)
$cp1Traversable :: forall k. TrieKey k => Functor (Row k)
Traversable)
instance (GT.TrieKey k) => Semigroup (Row k v) where
  Row Trie k v
r1 <> :: Row k v -> Row k v -> Row k v
<> Row Trie k v
r2 = Trie k v -> Row k v
forall k v. Trie k v -> Row k v
Row (Trie k v -> Row k v) -> Trie k v -> Row k v
forall a b. (a -> b) -> a -> b
$ Trie k v
r1 Trie k v -> Trie k v -> Trie k v
forall k a. TrieKey k => Trie k a -> Trie k a -> Trie k a
`GT.union` Trie k v
r2
instance GT.TrieKey k => Monoid (Row k v) where mempty :: Row k v
mempty = Trie k v -> Row k v
forall k v. Trie k v -> Row k v
Row Trie k v
forall k a. TrieKey k => Trie k a
GT.empty
-- makeLenses ''Row
instance (GT.TrieKey k, Show k, Show v) => Show (Row k v) where
  show :: Row k v -> String
show = [(k, v)] -> String
forall a. Show a => a -> String
show ([(k, v)] -> String) -> (Row k v -> [(k, v)]) -> Row k v -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Trie k v -> [(k, v)]
forall k a. TrieKey k => Trie k a -> [(k, a)]
GT.toList (Trie k v -> [(k, v)])
-> (Row k v -> Trie k v) -> Row k v -> [(k, v)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Row k v -> Trie k v
forall k v. Row k v -> Trie k v
_unRow

instance (GT.TrieKey k, Eq k, Eq v) => Eq (Row k v) where
  Row k v
r1 == :: Row k v -> Row k v -> Bool
== Row k v
r2 = Row k v -> [v]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList Row k v
r1 [v] -> [v] -> Bool
forall a. Eq a => a -> a -> Bool
== Row k v -> [v]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList Row k v
r2

instance (GT.TrieKey k, Eq k, Eq v, Ord k, Ord v) => Ord (Row k v) where
  Row k v
r1 <= :: Row k v -> Row k v -> Bool
<= Row k v
r2 = Row k v -> [v]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList Row k v
r1 [v] -> [v] -> Bool
forall a. Ord a => a -> a -> Bool
<= Row k v -> [v]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList Row k v
r2

-- | Focus on a given column
--
-- NB : setting a 'Nothing' value removes the entry
at :: GT.TrieKey k =>
      k -- ^ column index
   -> Lens' (Row k a) (Maybe a)
at :: k -> Lens' (Row k a) (Maybe a)
at k
k Maybe a -> f (Maybe a)
f Row k a
m = Maybe a -> f (Maybe a)
f Maybe a
mv f (Maybe a) -> (Maybe a -> Row k a) -> f (Row k a)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
    Maybe a
Nothing -> Row k a -> (a -> Row k a) -> Maybe a -> Row k a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Row k a
m (Row k a -> a -> Row k a
forall a b. a -> b -> a
const (k -> Row k a -> Row k a
forall k v. TrieKey k => k -> Row k v -> Row k v
delete k
k Row k a
m)) Maybe a
mv
    Just a
v' -> k -> a -> Row k a -> Row k a
forall k v. TrieKey k => k -> v -> Row k v -> Row k v
insert k
k a
v' Row k a
m
    where mv :: Maybe a
mv = k -> Row k a -> Maybe a
forall k v. TrieKey k => k -> Row k v -> Maybe v
lookup k
k Row k a
m
{-# INLINABLE at #-}

-- | 'atPrefix' : a Lens' that takes a key prefix and relates a row having lists as keys and the subset of columns corresponding to keys having that prefix
atPrefix :: (GT.TrieKey k, Eq k) =>
            [k] -- ^ key prefix of the columns of interest
         -> Lens' (Row [k] v) [v]
atPrefix :: [k] -> Lens' (Row [k] v) [v]
atPrefix [k]
k [v] -> f [v]
f Row [k] v
m = [v] -> f [v]
f [v]
vs f [v] -> ([v] -> Row [k] v) -> f (Row [k] v)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
  [] -> if [([k], v)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [([k], v)]
kvs then Row [k] v
m else [[k]] -> Row [k] v -> Row [k] v
forall k (t :: * -> *) v.
(TrieKey k, Foldable t) =>
t k -> Row k v -> Row k v
deleteMany [[k]]
ks Row [k] v
m
  [v]
vs' -> [([k], v)] -> Row [k] v -> Row [k] v
forall k (t :: * -> *) v.
(TrieKey k, Foldable t) =>
t (k, v) -> Row k v -> Row k v
insertMany ([[k]] -> [v] -> [([k], v)]
forall a b. [a] -> [b] -> [(a, b)]
zip [[k]]
ks [v]
vs') Row [k] v
m
  where
    kvs :: [([k], v)]
kvs = Row [k] v -> [([k], v)]
forall k v. TrieKey k => Row k v -> [(k, v)]
toList (Row [k] v -> [([k], v)]) -> Row [k] v -> [([k], v)]
forall a b. (a -> b) -> a -> b
$ [k] -> Row [k] v -> Row [k] v
forall a v. (TrieKey a, Eq a) => [a] -> Row [a] v -> Row [a] v
filterWithKeyPrefix [k]
k Row [k] v
m
    ([[k]]
ks, [v]
vs) = [([k], v)] -> ([[k]], [v])
forall a b. [(a, b)] -> ([a], [b])
unzip [([k], v)]
kvs

{- | Focus on all elements that share a common key prefix

e.g.

@
>>> :t \k -> 'Lens.Micro.toListOf' (eachPrefixed k . vpBool)
(GT.TrieKey k, Eq k) => [k] -> Row [k] VP -> [Bool]
@
-}
eachPrefixed :: (GT.TrieKey k, Eq k) =>
                [k] -- ^ key prefix of the columns of interest
             -> Traversal' (Row [k] v) v
eachPrefixed :: [k] -> Traversal' (Row [k] v) v
eachPrefixed [k]
k = [k] -> Lens' (Row [k] v) [v]
forall k v. (TrieKey k, Eq k) => [k] -> Lens' (Row [k] v) [v]
atPrefix [k]
k (([v] -> f [v]) -> Row [k] v -> f (Row [k] v))
-> ((v -> f v) -> [v] -> f [v])
-> (v -> f v)
-> Row [k] v
-> f (Row [k] v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (v -> f v) -> [v] -> f [v]
forall (f :: * -> *) a b.
Traversable f =>
Traversal (f a) (f b) a b
traversed

-- | Extract all elements that share a common key prefix into a monoidal value (e.g. a list)
foldPrefixed :: (GT.TrieKey k, Eq k, Monoid r) =>
                [k] -- ^ key prefix of the columns of interest
             -> Getting r (Row [k] v) v
foldPrefixed :: [k] -> Getting r (Row [k] v) v
foldPrefixed [k]
k = [k] -> Lens' (Row [k] v) [v]
forall k v. (TrieKey k, Eq k) => [k] -> Lens' (Row [k] v) [v]
atPrefix [k]
k (([v] -> Const r [v]) -> Row [k] v -> Const r (Row [k] v))
-> ((v -> Const r v) -> [v] -> Const r [v])
-> Getting r (Row [k] v) v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (v -> Const r v) -> [v] -> Const r [v]
forall (f :: * -> *) a. Foldable f => SimpleFold (f a) a
folded

-- foldingPrefixed f k = atPrefix k . folding f

-- any :: Eq a => a -> a -> Any
-- any v = Any . (== v)

-- | Helper for filtering 'Frame's
--
-- e.g.
--
-- >>> :t \k -> keep (text k) (== "hello")
--   :: GT.TrieKey k => k -> Row k VP -> Bool
keep :: Getting Any row a
     -> (a -> b) -- ^ e.g. a predicate
     -> row
     -> Bool
keep :: Getting Any row a -> (a -> b) -> row -> Bool
keep Getting Any row a
l a -> b
f = Getting Any row b -> row -> Bool
forall s a. Getting Any s a -> s -> Bool
has (Getting Any row a
l Getting Any row a
-> ((b -> Const Any b) -> a -> Const Any a) -> Getting Any row b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> SimpleGetter a b
forall s a. (s -> a) -> SimpleGetter s a
to a -> b
f)


-- keep :: (Eq a) => Getting Any row a -> a -> row -> Bool
-- keep l v = has (l . to (== v))


-- ** Getters

-- | Lookup a real number at the given index.
--
-- Matches `Double`, `Float`, `Int` and `Scientific` values.
real :: GT.TrieKey k => k -> Row k VP -> Maybe Double
real :: k -> Row k VP -> Maybe Double
real k
k Row k VP
r = Maybe Double
g1 Maybe Double -> Maybe Double -> Maybe Double
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Double
g2 Maybe Double -> Maybe Double -> Maybe Double
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Double
g3 Maybe Double -> Maybe Double -> Maybe Double
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Double
g4
  where
    g1 :: Maybe Double
g1 = Row k VP
r Row k VP
-> Getting (First Double) (Row k VP) Double -> Maybe Double
forall s a. s -> Getting (First a) s a -> Maybe a
^? k -> Traversal' (Row k VP) Int
forall k. TrieKey k => k -> Traversal' (Row k VP) Int
int k
k ((Int -> Const (First Double) Int)
 -> Row k VP -> Const (First Double) (Row k VP))
-> ((Double -> Const (First Double) Double)
    -> Int -> Const (First Double) Int)
-> Getting (First Double) (Row k VP) Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Double) -> SimpleGetter Int Double
forall s a. (s -> a) -> SimpleGetter s a
to Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral
    g2 :: Maybe Double
g2 = Row k VP
r Row k VP
-> Getting (First Double) (Row k VP) Double -> Maybe Double
forall s a. s -> Getting (First a) s a -> Maybe a
^? k -> Traversal' (Row k VP) Double
forall k. TrieKey k => k -> Traversal' (Row k VP) Double
double k
k
    g3 :: Maybe Double
g3 = Row k VP
r Row k VP
-> Getting (First Double) (Row k VP) Double -> Maybe Double
forall s a. s -> Getting (First a) s a -> Maybe a
^? k -> Traversal' (Row k VP) Float
forall k. TrieKey k => k -> Traversal' (Row k VP) Float
float k
k ((Float -> Const (First Double) Float)
 -> Row k VP -> Const (First Double) (Row k VP))
-> ((Double -> Const (First Double) Double)
    -> Float -> Const (First Double) Float)
-> Getting (First Double) (Row k VP) Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Double) -> SimpleGetter Float Double
forall s a. (s -> a) -> SimpleGetter s a
to (Rational -> Double
forall a. Fractional a => Rational -> a
fromRational (Rational -> Double) -> (Float -> Rational) -> Float -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Rational
forall a. Real a => a -> Rational
toRational)
    g4 :: Maybe Double
g4 = Row k VP
r Row k VP
-> Getting (First Double) (Row k VP) Double -> Maybe Double
forall s a. s -> Getting (First a) s a -> Maybe a
^? k -> Traversal' (Row k VP) Scientific
forall k. TrieKey k => k -> Traversal' (Row k VP) Scientific
scientific k
k ((Scientific -> Const (First Double) Scientific)
 -> Row k VP -> Const (First Double) (Row k VP))
-> ((Double -> Const (First Double) Double)
    -> Scientific -> Const (First Double) Scientific)
-> Getting (First Double) (Row k VP) Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Scientific -> Double) -> SimpleGetter Scientific Double
forall s a. (s -> a) -> SimpleGetter s a
to (Rational -> Double
forall a. Fractional a => Rational -> a
fromRational (Rational -> Double)
-> (Scientific -> Rational) -> Scientific -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scientific -> Rational
forall a. Real a => a -> Rational
toRational)

-- | Look up a text string at the given index.
--
-- Matches `String` and `Text` values.
txt :: GT.TrieKey k => k -> Row k VP -> Maybe Text
txt :: k -> Row k VP -> Maybe Text
txt k
k Row k VP
r = Maybe Text
g1 Maybe Text -> Maybe Text -> Maybe Text
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Text
g2
  where
    g1 :: Maybe Text
g1 = Row k VP
r Row k VP -> Getting (First Text) (Row k VP) Text -> Maybe Text
forall s a. s -> Getting (First a) s a -> Maybe a
^? k -> Traversal' (Row k VP) String
forall k. TrieKey k => k -> Traversal' (Row k VP) String
string k
k ((String -> Const (First Text) String)
 -> Row k VP -> Const (First Text) (Row k VP))
-> ((Text -> Const (First Text) Text)
    -> String -> Const (First Text) String)
-> Getting (First Text) (Row k VP) Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Text) -> SimpleGetter String Text
forall s a. (s -> a) -> SimpleGetter s a
to String -> Text
T.pack
    g2 :: Maybe Text
g2 = Row k VP
r Row k VP -> Getting (First Text) (Row k VP) Text -> Maybe Text
forall s a. s -> Getting (First a) s a -> Maybe a
^? k -> Traversal' (Row k VP) Text
forall k. TrieKey k => k -> Traversal' (Row k VP) Text
text k
k

-- -- | Lookup a "flag" at the given index.
-- --
-- -- `Bool`ean values and 
-- flag :: GT.TrieKey k => k -> Row k VP -> Maybe Bool
-- flag k r = g1 <|> g2
--   where
--     g1 = r ^? bool k
--     g2 = r ^? char k . to f
--     f c = elem c ['y', 'Y']

-- class Contains a where
--   contains_ :: GT.TrieKey k => k -> Traversal' (Row k VP) a

-- instance Contains Int where contains_ = int
-- instance Contains Char where contains_ = char

-- contains :: (Contains a, Eq a, GT.TrieKey k, Monoid r, Foldable t) =>
--             k
--          -> t a
--          -> Getting r (Row k VP) Bool
-- contains k xs = contains_ k . to (`elem` xs)

-- ** Lenses

-- | Decode a 'Bool' from the given column index
bool :: GT.TrieKey k => k -> Traversal' (Row k VP) Bool
bool :: k -> Traversal' (Row k VP) Bool
bool k
k = k -> Lens' (Row k VP) (Maybe VP)
forall k a. TrieKey k => k -> Lens' (Row k a) (Maybe a)
at k
k ((Maybe VP -> f (Maybe VP)) -> Row k VP -> f (Row k VP))
-> ((Bool -> f Bool) -> Maybe VP -> f (Maybe VP))
-> (Bool -> f Bool)
-> Row k VP
-> f (Row k VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VP -> f VP) -> Maybe VP -> f (Maybe VP)
forall a a'. Traversal (Maybe a) (Maybe a') a a'
_Just ((VP -> f VP) -> Maybe VP -> f (Maybe VP))
-> ((Bool -> f Bool) -> VP -> f VP)
-> (Bool -> f Bool)
-> Maybe VP
-> f (Maybe VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> f Bool) -> VP -> f VP
Traversal' VP Bool
vpBool
-- | Decode a 'Int' from the given column index
int :: GT.TrieKey k => k -> Traversal' (Row k VP) Int
int :: k -> Traversal' (Row k VP) Int
int k
k = k -> Lens' (Row k VP) (Maybe VP)
forall k a. TrieKey k => k -> Lens' (Row k a) (Maybe a)
at k
k ((Maybe VP -> f (Maybe VP)) -> Row k VP -> f (Row k VP))
-> ((Int -> f Int) -> Maybe VP -> f (Maybe VP))
-> (Int -> f Int)
-> Row k VP
-> f (Row k VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VP -> f VP) -> Maybe VP -> f (Maybe VP)
forall a a'. Traversal (Maybe a) (Maybe a') a a'
_Just ((VP -> f VP) -> Maybe VP -> f (Maybe VP))
-> ((Int -> f Int) -> VP -> f VP)
-> (Int -> f Int)
-> Maybe VP
-> f (Maybe VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> f Int) -> VP -> f VP
Traversal' VP Int
vpInt
-- | Decode a 'Float' from the given column index
float :: GT.TrieKey k => k -> Traversal' (Row k VP) Float
float :: k -> Traversal' (Row k VP) Float
float k
k = k -> Lens' (Row k VP) (Maybe VP)
forall k a. TrieKey k => k -> Lens' (Row k a) (Maybe a)
at k
k ((Maybe VP -> f (Maybe VP)) -> Row k VP -> f (Row k VP))
-> ((Float -> f Float) -> Maybe VP -> f (Maybe VP))
-> (Float -> f Float)
-> Row k VP
-> f (Row k VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VP -> f VP) -> Maybe VP -> f (Maybe VP)
forall a a'. Traversal (Maybe a) (Maybe a') a a'
_Just ((VP -> f VP) -> Maybe VP -> f (Maybe VP))
-> ((Float -> f Float) -> VP -> f VP)
-> (Float -> f Float)
-> Maybe VP
-> f (Maybe VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> f Float) -> VP -> f VP
Traversal' VP Float
vpFloat
-- | Decode a 'Double' from the given column index
double :: GT.TrieKey k => k -> Traversal' (Row k VP) Double
double :: k -> Traversal' (Row k VP) Double
double k
k = k -> Lens' (Row k VP) (Maybe VP)
forall k a. TrieKey k => k -> Lens' (Row k a) (Maybe a)
at k
k ((Maybe VP -> f (Maybe VP)) -> Row k VP -> f (Row k VP))
-> ((Double -> f Double) -> Maybe VP -> f (Maybe VP))
-> (Double -> f Double)
-> Row k VP
-> f (Row k VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VP -> f VP) -> Maybe VP -> f (Maybe VP)
forall a a'. Traversal (Maybe a) (Maybe a') a a'
_Just ((VP -> f VP) -> Maybe VP -> f (Maybe VP))
-> ((Double -> f Double) -> VP -> f VP)
-> (Double -> f Double)
-> Maybe VP
-> f (Maybe VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> f Double) -> VP -> f VP
Traversal' VP Double
vpDouble
-- | Decode a 'Char' from the given column index
char :: GT.TrieKey k => k -> Traversal' (Row k VP) Char
char :: k -> Traversal' (Row k VP) Char
char k
k = k -> Lens' (Row k VP) (Maybe VP)
forall k a. TrieKey k => k -> Lens' (Row k a) (Maybe a)
at k
k ((Maybe VP -> f (Maybe VP)) -> Row k VP -> f (Row k VP))
-> ((Char -> f Char) -> Maybe VP -> f (Maybe VP))
-> (Char -> f Char)
-> Row k VP
-> f (Row k VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VP -> f VP) -> Maybe VP -> f (Maybe VP)
forall a a'. Traversal (Maybe a) (Maybe a') a a'
_Just ((VP -> f VP) -> Maybe VP -> f (Maybe VP))
-> ((Char -> f Char) -> VP -> f VP)
-> (Char -> f Char)
-> Maybe VP
-> f (Maybe VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> f Char) -> VP -> f VP
Traversal' VP Char
vpChar
-- | Decode a 'String' from the given column index
string :: GT.TrieKey k => k -> Traversal' (Row k VP) String
string :: k -> Traversal' (Row k VP) String
string k
k = k -> Lens' (Row k VP) (Maybe VP)
forall k a. TrieKey k => k -> Lens' (Row k a) (Maybe a)
at k
k ((Maybe VP -> f (Maybe VP)) -> Row k VP -> f (Row k VP))
-> ((String -> f String) -> Maybe VP -> f (Maybe VP))
-> (String -> f String)
-> Row k VP
-> f (Row k VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VP -> f VP) -> Maybe VP -> f (Maybe VP)
forall a a'. Traversal (Maybe a) (Maybe a') a a'
_Just ((VP -> f VP) -> Maybe VP -> f (Maybe VP))
-> ((String -> f String) -> VP -> f VP)
-> (String -> f String)
-> Maybe VP
-> f (Maybe VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> f String) -> VP -> f VP
Traversal' VP String
vpString
-- | Decode a 'Text' from the given column index
text :: GT.TrieKey k => k -> Traversal' (Row k VP) Text
text :: k -> Traversal' (Row k VP) Text
text k
k = k -> Lens' (Row k VP) (Maybe VP)
forall k a. TrieKey k => k -> Lens' (Row k a) (Maybe a)
at k
k ((Maybe VP -> f (Maybe VP)) -> Row k VP -> f (Row k VP))
-> ((Text -> f Text) -> Maybe VP -> f (Maybe VP))
-> (Text -> f Text)
-> Row k VP
-> f (Row k VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VP -> f VP) -> Maybe VP -> f (Maybe VP)
forall a a'. Traversal (Maybe a) (Maybe a') a a'
_Just ((VP -> f VP) -> Maybe VP -> f (Maybe VP))
-> ((Text -> f Text) -> VP -> f VP)
-> (Text -> f Text)
-> Maybe VP
-> f (Maybe VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> f Text) -> VP -> f VP
Traversal' VP Text
vpText
-- | Decode a 'Scientific' from the given column index
scientific :: GT.TrieKey k => k -> Traversal' (Row k VP) Scientific
scientific :: k -> Traversal' (Row k VP) Scientific
scientific k
k = k -> Lens' (Row k VP) (Maybe VP)
forall k a. TrieKey k => k -> Lens' (Row k a) (Maybe a)
at k
k ((Maybe VP -> f (Maybe VP)) -> Row k VP -> f (Row k VP))
-> ((Scientific -> f Scientific) -> Maybe VP -> f (Maybe VP))
-> (Scientific -> f Scientific)
-> Row k VP
-> f (Row k VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VP -> f VP) -> Maybe VP -> f (Maybe VP)
forall a a'. Traversal (Maybe a) (Maybe a') a a'
_Just ((VP -> f VP) -> Maybe VP -> f (Maybe VP))
-> ((Scientific -> f Scientific) -> VP -> f VP)
-> (Scientific -> f Scientific)
-> Maybe VP
-> f (Maybe VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Scientific -> f Scientific) -> VP -> f VP
Traversal' VP Scientific
vpScientific
-- | Decode a 'OneHot' from the given column index
oneHot :: GT.TrieKey k => k -> Traversal' (Row k VP) (OneHot Int)
oneHot :: k -> Traversal' (Row k VP) (OneHot Int)
oneHot k
k = k -> Lens' (Row k VP) (Maybe VP)
forall k a. TrieKey k => k -> Lens' (Row k a) (Maybe a)
at k
k ((Maybe VP -> f (Maybe VP)) -> Row k VP -> f (Row k VP))
-> ((OneHot Int -> f (OneHot Int)) -> Maybe VP -> f (Maybe VP))
-> (OneHot Int -> f (OneHot Int))
-> Row k VP
-> f (Row k VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VP -> f VP) -> Maybe VP -> f (Maybe VP)
forall a a'. Traversal (Maybe a) (Maybe a') a a'
_Just ((VP -> f VP) -> Maybe VP -> f (Maybe VP))
-> ((OneHot Int -> f (OneHot Int)) -> VP -> f VP)
-> (OneHot Int -> f (OneHot Int))
-> Maybe VP
-> f (Maybe VP)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (OneHot Int -> f (OneHot Int)) -> VP -> f VP
Traversal' VP (OneHot Int)
vpOneHot







-- | Construct a 'Row' from a list of key-element pairs.
--
-- >>> lookup 3 (rowFromList [(3,'a'),(4,'b')])
-- Just 'a'
-- >>> lookup 6 (rowFromList [(3,'a'),(4,'b')])
-- Nothing
rowFromList :: GT.TrieKey k => [(k, v)] -> Row k v
rowFromList :: [(k, v)] -> Row k v
rowFromList = Trie k v -> Row k v
forall k v. Trie k v -> Row k v
Row (Trie k v -> Row k v)
-> ([(k, v)] -> Trie k v) -> [(k, v)] -> Row k v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(k, v)] -> Trie k v
forall k v. TrieKey k => [(k, v)] -> Trie k v
GT.fromList

-- | Construct a 'Row' from a trie (unsafe).
mkRow :: GT.Trie k v -> Row k v
mkRow :: Trie k v -> Row k v
mkRow = Trie k v -> Row k v
forall k v. Trie k v -> Row k v
Row

-- | An empty row
empty :: GT.TrieKey k => Row k v
empty :: Row k v
empty = Trie k v -> Row k v
forall k v. Trie k v -> Row k v
Row Trie k v
forall k a. TrieKey k => Trie k a
GT.empty

-- | Access the key-value pairs contained in the 'Row'
toList :: GT.TrieKey k => Row k v -> [(k ,v)]
toList :: Row k v -> [(k, v)]
toList = Trie k v -> [(k, v)]
forall k a. TrieKey k => Trie k a -> [(k, a)]
GT.toList (Trie k v -> [(k, v)])
-> (Row k v -> Trie k v) -> Row k v -> [(k, v)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Row k v -> Trie k v
forall k v. Row k v -> Trie k v
_unRow

-- | Lookup the value stored at a given key in a row
--
-- >>> lookup 0 row0
-- Just 'a'
-- >>> lookup 1 row0
-- Nothing
lookup :: (GT.TrieKey k) => k -> Row k v -> Maybe v
lookup :: k -> Row k v -> Maybe v
lookup k
k = k -> Trie k v -> Maybe v
forall k a. TrieKey k => k -> Trie k a -> Maybe a
GT.lookup k
k (Trie k v -> Maybe v)
-> (Row k v -> Trie k v) -> Row k v -> Maybe v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Row k v -> Trie k v
forall k v. Row k v -> Trie k v
_unRow

liftLookup :: GT.TrieKey k =>
              (a -> b -> c) -> k -> Row k a -> Row k b -> Maybe c
liftLookup :: (a -> b -> c) -> k -> Row k a -> Row k b -> Maybe c
liftLookup a -> b -> c
f k
k Row k a
r1 Row k b
r2 = a -> b -> c
f (a -> b -> c) -> Maybe a -> Maybe (b -> c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> k -> Row k a -> Maybe a
forall k v. TrieKey k => k -> Row k v -> Maybe v
lookup k
k Row k a
r1 Maybe (b -> c) -> Maybe b -> Maybe c
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> k -> Row k b -> Maybe b
forall k v. TrieKey k => k -> Row k v -> Maybe v
lookup k
k Row k b
r2


-- | Compares for ordering two rows by the values indexed at a specific key.
--
-- Returns Nothing if the key is not present in either row.
compareByLookup :: (GT.TrieKey k, Eq k, Ord a) =>
                   k -> Row k a -> Row k a -> Maybe Ordering
compareByLookup :: k -> Row k a -> Row k a -> Maybe Ordering
compareByLookup = (a -> a -> Ordering) -> k -> Row k a -> Row k a -> Maybe Ordering
forall k a b c.
TrieKey k =>
(a -> b -> c) -> k -> Row k a -> Row k b -> Maybe c
liftLookup a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare

-- | Compares two rows by the values indexed at a specific key.
--
-- Returns Nothing if the key is not present in either row.
eqByLookup :: (GT.TrieKey k, Eq k, Eq a) =>
              k -> Row k a -> Row k a -> Maybe Bool
eqByLookup :: k -> Row k a -> Row k a -> Maybe Bool
eqByLookup = (a -> a -> Bool) -> k -> Row k a -> Row k a -> Maybe Bool
forall k a b c.
TrieKey k =>
(a -> b -> c) -> k -> Row k a -> Row k b -> Maybe c
liftLookup a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(==)

-- | Compares two rows by the values indexed at a set of keys.
--
-- Returns Nothing if a key in either row is not present.
eqByLookups :: (Foldable t, GT.TrieKey k, Eq k, Eq a) =>
               t k -> Row k a -> Row k a -> Maybe Bool
eqByLookups :: t k -> Row k a -> Row k a -> Maybe Bool
eqByLookups t k
ks Row k a
r1 Row k a
r2 = (Bool -> k -> Maybe Bool) -> Bool -> t k -> Maybe Bool
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
F.foldlM Bool -> k -> Maybe Bool
insf Bool
True t k
ks where
  insf :: Bool -> k -> Maybe Bool
insf Bool
b k
k = (Bool -> Bool) -> Maybe (Bool -> Bool)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Bool -> Bool -> Bool
(&&)) Bool
b) Maybe (Bool -> Bool) -> Maybe Bool -> Maybe Bool
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> k -> Row k a -> Row k a -> Maybe Bool
forall k a.
(TrieKey k, Eq k, Eq a) =>
k -> Row k a -> Row k a -> Maybe Bool
eqByLookup k
k Row k a
r1 Row k a
r2

-- -- | Like 'lookup', but throws a 'KeyError' if the lookup is unsuccessful
-- lookupThrowM :: (MonadThrow m, Show k, Typeable k, GT.TrieKey k) =>
--                 k -> Row k v -> m v
-- lookupThrowM k r = maybe (throwM $ MissingKeyError k) pure (lookup k r)

-- | Returns an empty row if the argument is Nothing.
maybeEmpty :: GT.TrieKey k => Maybe (Row k v) -> Row k v
maybeEmpty :: Maybe (Row k v) -> Row k v
maybeEmpty = Row k v -> Maybe (Row k v) -> Row k v
forall a. a -> Maybe a -> a
fromMaybe Row k v
forall k v. TrieKey k => Row k v
empty

-- | List the keys of a given row
--
-- >>> keys row0
-- [0,3]
keys :: GT.TrieKey k => Row k v -> [k]
keys :: Row k v -> [k]
keys = ((k, v) -> k) -> [(k, v)] -> [k]
forall a b. (a -> b) -> [a] -> [b]
map (k, v) -> k
forall a b. (a, b) -> a
fst ([(k, v)] -> [k]) -> (Row k v -> [(k, v)]) -> Row k v -> [k]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Row k v -> [(k, v)]
forall k v. TrieKey k => Row k v -> [(k, v)]
toList

-- | Takes the union of a Foldable container of 'Row's and discards the values
keysOnly :: (GT.TrieKey k, Foldable f) => f (Row k v) -> Row k ()
keysOnly :: f (Row k v) -> Row k ()
keysOnly f (Row k v)
ks = () () -> Row k v -> Row k ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (Row k v -> Row k v -> Row k v)
-> Row k v -> f (Row k v) -> Row k v
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' Row k v -> Row k v -> Row k v
forall k v. TrieKey k => Row k v -> Row k v -> Row k v
union Row k v
forall k v. TrieKey k => Row k v
empty f (Row k v)
ks

-- | Returns a new 'Row' that doesn't have a given key-value pair
delete :: GT.TrieKey k =>
          k       -- ^ Key to remove
       -> Row k v
       -> Row k v
delete :: k -> Row k v -> Row k v
delete k
k (Row Trie k v
gt) = Trie k v -> Row k v
forall k v. Trie k v -> Row k v
Row (Trie k v -> Row k v) -> Trie k v -> Row k v
forall a b. (a -> b) -> a -> b
$ k -> Trie k v -> Trie k v
forall k a. TrieKey k => k -> Trie k a -> Trie k a
GT.delete k
k Trie k v
gt

-- | Produce a new 'Row' such that its keys do _not_ belong to a certain set.
deleteMany :: (GT.TrieKey k, Foldable t) => t k -> Row k v -> Row k v
deleteMany :: t k -> Row k v -> Row k v
deleteMany t k
ks Row k v
r = (Row k v -> k -> Row k v) -> Row k v -> t k -> Row k v
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl ((k -> Row k v -> Row k v) -> Row k v -> k -> Row k v
forall a b c. (a -> b -> c) -> b -> a -> c
flip k -> Row k v -> Row k v
forall k v. TrieKey k => k -> Row k v -> Row k v
delete) Row k v
r t k
ks

-- | Map over all elements with a function of both the key and the value
mapWithKey :: GT.TrieKey k => (k -> a -> b) -> Row k a -> Row k b
mapWithKey :: (k -> a -> b) -> Row k a -> Row k b
mapWithKey k -> a -> b
ff (Row Trie k a
gt) =
  Identity (Row k b) -> Row k b
forall a. Identity a -> a
runIdentity (Identity (Row k b) -> Row k b) -> Identity (Row k b) -> Row k b
forall a b. (a -> b) -> a -> b
$ Trie k b -> Row k b
forall k v. Trie k v -> Row k v
Row (Trie k b -> Row k b) -> Identity (Trie k b) -> Identity (Row k b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (k -> a -> Identity b) -> Trie k a -> Identity (Trie k b)
forall k (f :: * -> *) a b.
(TrieKey k, Applicative f) =>
(k -> a -> f b) -> Trie k a -> f (Trie k b)
GT.traverseWithKey (\k
k a
v -> b -> Identity b
forall (f :: * -> *) a. Applicative f => a -> f a
pure (k -> a -> b
ff k
k a
v)) Trie k a
gt


-- | Filter a row by applying a predicate to its keys and corresponding elements.
--
-- NB : filtering _retains_ the elements that satisfy the predicate.
filterWithKey :: GT.TrieKey k => (k -> v -> Bool) -> Row k v -> Row k v
filterWithKey :: (k -> v -> Bool) -> Row k v -> Row k v
filterWithKey k -> v -> Bool
ff (Row Trie k v
gt) = Trie k v -> Row k v
forall k v. Trie k v -> Row k v
Row (Trie k v -> Row k v) -> Trie k v -> Row k v
forall a b. (a -> b) -> a -> b
$ (k -> v -> Bool) -> Trie k v -> Trie k v
forall k a. TrieKey k => (k -> a -> Bool) -> Trie k a -> Trie k a
GT.filterWithKey k -> v -> Bool
ff Trie k v
gt

-- | Retains the entries for which the given list is a prefix of the indexing key
filterWithKeyPrefix :: (GT.TrieKey a, Eq a) =>
                       [a] -- ^ key prefix
                    -> Row [a] v
                    -> Row [a] v
filterWithKeyPrefix :: [a] -> Row [a] v -> Row [a] v
filterWithKeyPrefix [a]
kpre = ([a] -> v -> Bool) -> Row [a] v -> Row [a] v
forall k v. TrieKey k => (k -> v -> Bool) -> Row k v -> Row k v
filterWithKey (\[a]
k v
_ -> [a]
kpre [a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` [a]
k)

-- | Partition a 'Row' into two new ones, such as the elements that satisfy the predicate will end up in the _left_ row.
partitionWithKey :: GT.TrieKey k =>
                    (k -> v -> Bool) -- ^ predicate
                 -> Row k v
                 -> (Row k v, Row k v)
partitionWithKey :: (k -> v -> Bool) -> Row k v -> (Row k v, Row k v)
partitionWithKey k -> v -> Bool
qf = (k -> v -> (Row k v, Row k v) -> (Row k v, Row k v))
-> (Row k v, Row k v) -> Row k v -> (Row k v, Row k v)
forall k a r. TrieKey k => (k -> a -> r -> r) -> r -> Row k a -> r
foldWithKey k -> v -> (Row k v, Row k v) -> (Row k v, Row k v)
insf (Row k v
forall k v. TrieKey k => Row k v
empty, Row k v
forall k v. TrieKey k => Row k v
empty)
  where
    insf :: k -> v -> (Row k v, Row k v) -> (Row k v, Row k v)
insf k
k v
v (Row k v
lacc, Row k v
racc) | k -> v -> Bool
qf k
k v
v    = (k -> v -> Row k v -> Row k v
forall k v. TrieKey k => k -> v -> Row k v -> Row k v
insert k
k v
v Row k v
lacc, Row k v
racc)
                          | Bool
otherwise = (Row k v
lacc, k -> v -> Row k v -> Row k v
forall k v. TrieKey k => k -> v -> Row k v -> Row k v
insert k
k v
v Row k v
racc)

-- | Uses 'partitionWithKey' internally
partitionWithKeyPrefix :: (GT.TrieKey a, Eq a) =>
                          [a] -- ^ key prefix
                       -> Row [a] v
                       -> (Row [a] v, Row [a] v)
partitionWithKeyPrefix :: [a] -> Row [a] v -> (Row [a] v, Row [a] v)
partitionWithKeyPrefix [a]
kpre = ([a] -> v -> Bool) -> Row [a] v -> (Row [a] v, Row [a] v)
forall k v.
TrieKey k =>
(k -> v -> Bool) -> Row k v -> (Row k v, Row k v)
partitionWithKey (\[a]
k v
_ -> [a]
kpre [a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` [a]
k)

-- | Retains the entries for which the given item appears at any position in the indexing key
filterWithKeyAny :: (GT.TrieKey a, Eq a) => a -> Row [a] v -> Row [a] v
filterWithKeyAny :: a -> Row [a] v -> Row [a] v
filterWithKeyAny a
kany = ([a] -> v -> Bool) -> Row [a] v -> Row [a] v
forall k v. TrieKey k => (k -> v -> Bool) -> Row k v -> Row k v
filterWithKey (\[a]
k v
_ -> a
kany a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [a]
k)




-- alter k m = fromMaybe m $ do
--   v <- lookup k m 
--   delete k m

-- alter k f t =
--   case f (lookup k t) of
--     Just v' -> insert k v' t
--     Nothing -> delete k t

-- modify k v = 


-- | Insert a key-value pair into a row and return the updated one
-- 
-- >>> keys $ insert 2 'y' row0
-- [0,2,3]
insert :: (GT.TrieKey k) => k -> v -> Row k v -> Row k v
insert :: k -> v -> Row k v -> Row k v
insert k
k v
v = Trie k v -> Row k v
forall k v. Trie k v -> Row k v
Row (Trie k v -> Row k v)
-> (Row k v -> Trie k v) -> Row k v -> Row k v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. k -> v -> Trie k v -> Trie k v
forall k a. TrieKey k => k -> a -> Trie k a -> Trie k a
GT.insert k
k v
v (Trie k v -> Trie k v)
-> (Row k v -> Trie k v) -> Row k v -> Trie k v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Row k v -> Trie k v
forall k v. Row k v -> Trie k v
_unRow

insertMany :: (GT.TrieKey k, Foldable t) => t (k, v) -> Row k v -> Row k v
insertMany :: t (k, v) -> Row k v -> Row k v
insertMany t (k, v)
kvs Row k v
r = (Row k v -> (k, v) -> Row k v) -> Row k v -> t (k, v) -> Row k v
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\Row k v
acc (k
k, v
v) -> k -> v -> Row k v -> Row k v
forall k v. TrieKey k => k -> v -> Row k v -> Row k v
insert k
k v
v Row k v
acc) Row k v
r t (k, v)
kvs

-- | Insert a key-value pair into a row and return the updated one, or updates the value by using the combination function.
insertWith :: (GT.TrieKey k) => (v -> v -> v) -> k -> v -> Row k v -> Row k v
insertWith :: (v -> v -> v) -> k -> v -> Row k v -> Row k v
insertWith v -> v -> v
f k
k v
v = Trie k v -> Row k v
forall k v. Trie k v -> Row k v
Row (Trie k v -> Row k v)
-> (Row k v -> Trie k v) -> Row k v -> Row k v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (v -> v -> v) -> k -> v -> Trie k v -> Trie k v
forall k v.
TrieKey k =>
(v -> v -> v) -> k -> v -> Trie k v -> Trie k v
GT.insertWith v -> v -> v
f k
k v
v (Trie k v -> Trie k v)
-> (Row k v -> Trie k v) -> Row k v -> Trie k v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Row k v -> Trie k v
forall k v. Row k v -> Trie k v
_unRow

-- | Fold over a row with a function of both key and value
foldWithKey :: GT.TrieKey k => (k -> a -> r -> r) -> r -> Row k a -> r
foldWithKey :: (k -> a -> r -> r) -> r -> Row k a -> r
foldWithKey k -> a -> r -> r
fk r
z (Row Trie k a
gt) = (k -> a -> r -> r) -> r -> Trie k a -> r
forall k a r. TrieKey k => (k -> a -> r -> r) -> r -> Trie k a -> r
GT.foldWithKey k -> a -> r -> r
fk r
z Trie k a
gt

-- | Traverse a 'Row' using a function of both the key and the element.
traverseWithKey :: (Applicative f, GT.TrieKey k) => (k -> a -> f b) -> Row k a -> f (Row k b)
traverseWithKey :: (k -> a -> f b) -> Row k a -> f (Row k b)
traverseWithKey k -> a -> f b
f Row k a
r = Trie k b -> Row k b
forall k v. Trie k v -> Row k v
Row (Trie k b -> Row k b) -> f (Trie k b) -> f (Row k b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (k -> a -> f b) -> Trie k a -> f (Trie k b)
forall k (f :: * -> *) a b.
(TrieKey k, Applicative f) =>
(k -> a -> f b) -> Trie k a -> f (Trie k b)
GT.traverseWithKey k -> a -> f b
f (Row k a -> Trie k a
forall k v. Row k v -> Trie k v
_unRow Row k a
r)


-- | Set union of two rows
--
-- >>> keys $ union row0 row1
-- [0,1,3,666]
union :: (GT.TrieKey k) => Row k v -> Row k v -> Row k v
union :: Row k v -> Row k v -> Row k v
union Row k v
r1 Row k v
r2 = Trie k v -> Row k v
forall k v. Trie k v -> Row k v
Row (Trie k v -> Row k v) -> Trie k v -> Row k v
forall a b. (a -> b) -> a -> b
$ Trie k v -> Trie k v -> Trie k v
forall k a. TrieKey k => Trie k a -> Trie k a -> Trie k a
GT.union (Row k v -> Trie k v
forall k v. Row k v -> Trie k v
_unRow Row k v
r1) (Row k v -> Trie k v
forall k v. Row k v -> Trie k v
_unRow Row k v
r2)

-- | Set union of two rows, using a combining function for equal keys
unionWith :: (GT.TrieKey k) =>
             (v -> v -> v) -> Row k v -> Row k v -> Row k v
unionWith :: (v -> v -> v) -> Row k v -> Row k v -> Row k v
unionWith v -> v -> v
f Row k v
r1 Row k v
r2 = Trie k v -> Row k v
forall k v. Trie k v -> Row k v
Row (Trie k v -> Row k v) -> Trie k v -> Row k v
forall a b. (a -> b) -> a -> b
$ (v -> v -> v) -> Trie k v -> Trie k v -> Trie k v
forall k a.
TrieKey k =>
(a -> a -> a) -> Trie k a -> Trie k a -> Trie k a
GT.unionWith v -> v -> v
f (Row k v -> Trie k v
forall k v. Row k v -> Trie k v
_unRow Row k v
r1) (Row k v -> Trie k v
forall k v. Row k v -> Trie k v
_unRow Row k v
r2)

-- | Set intersection of two rows
intersection :: GT.TrieKey k => Row k v -> Row k b -> Row k v
intersection :: Row k v -> Row k b -> Row k v
intersection Row k v
r1 Row k b
r2 = Trie k v -> Row k v
forall k v. Trie k v -> Row k v
Row (Trie k v -> Row k v) -> Trie k v -> Row k v
forall a b. (a -> b) -> a -> b
$ Trie k v -> Trie k b -> Trie k v
forall k a b. TrieKey k => Trie k a -> Trie k b -> Trie k a
GT.intersection (Row k v -> Trie k v
forall k v. Row k v -> Trie k v
_unRow Row k v
r1) (Row k b -> Trie k b
forall k v. Row k v -> Trie k v
_unRow Row k b
r2)

-- | Set intersections of two rows, using a combining function for equal keys
intersectionWith :: GT.TrieKey k => (a -> b -> v) -> Row k a -> Row k b -> Row k v
intersectionWith :: (a -> b -> v) -> Row k a -> Row k b -> Row k v
intersectionWith a -> b -> v
f Row k a
r1 Row k b
r2 = Trie k v -> Row k v
forall k v. Trie k v -> Row k v
Row (Trie k v -> Row k v) -> Trie k v -> Row k v
forall a b. (a -> b) -> a -> b
$ (a -> b -> v) -> Trie k a -> Trie k b -> Trie k v
forall k a b c.
TrieKey k =>
(a -> b -> c) -> Trie k a -> Trie k b -> Trie k c
GT.intersectionWith a -> b -> v
f (Row k a -> Trie k a
forall k v. Row k v -> Trie k v
_unRow Row k a
r1) (Row k b -> Trie k b
forall k v. Row k v -> Trie k v
_unRow Row k b
r2)


-- | Looks up a key from a row and applies a predicate to its value (if this is found). If no value is found at that key the function returns False.
--
-- This function is meant to be used as first argument to 'filter'.
--
-- >>> elemSatisfies (== 'a') 0 row0
-- True
-- >>> elemSatisfies (== 'a') 42 row0
-- False
elemSatisfies :: (GT.TrieKey k) => (a -> Bool) -> k -> Row k a -> Bool
elemSatisfies :: (a -> Bool) -> k -> Row k a -> Bool
elemSatisfies a -> Bool
f k
k Row k a
row = Bool -> (a -> Bool) -> Maybe a -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False a -> Bool
f (k -> Row k a -> Maybe a
forall k v. TrieKey k => k -> Row k v -> Maybe v
lookup k
k Row k a
row)

-- | Inline synonym for 'elemSatisfies'
(!:) :: (GT.TrieKey k) => k -> (a -> Bool) -> Row k a -> Bool
k
k !: :: k -> (a -> Bool) -> Row k a -> Bool
!: a -> Bool
f = (a -> Bool) -> k -> Row k a -> Bool
forall k a. TrieKey k => (a -> Bool) -> k -> Row k a -> Bool
elemSatisfies a -> Bool
f k
k

-- -- | Lookup a value from a Row indexed at the given key (returns in a MonadThrow type)
-- lookupColM :: (MonadThrow m, Show k, Typeable k, GT.TrieKey k) =>
--               k -> D.Decode m (Row k o) o
-- lookupColM k = D.mkDecode (lookupThrowM k)

-- -- -- | Lookup a value from a Row indexed at the given key (returns in the Maybe monad)
-- -- lookupCol :: GT.TrieKey k => k -> D.Decode Maybe (Row k o) o
-- -- lookupCol k = D.mkDecode (lookup k)





-- -- * Decoders

-- -- | Lookup and decode a real number
-- real :: (MonadThrow m, Show k, Typeable k, GT.TrieKey k, Alternative m) =>
--         k -> D.Decode m (Row k VP) Double
-- real k = lookupColM k >>> realM

-- -- | Lookup and decode a real 'Scientific' value
-- scientific :: (MonadThrow m, Show k, Typeable k, GT.TrieKey k, Alternative m) =>
--               k -> D.Decode m (Row k VP) Scientific
-- scientific k = lookupColM k >>> scientificM

-- -- | Lookup and decode a text string (defaults to Text)
-- text :: (MonadThrow m, Show k, Typeable k, GT.TrieKey k, Alternative m) =>
--         k -> D.Decode m (Row k VP) Text
-- text k = lookupColM k >>> textM

-- -- | Lookup and decode a text string (defaults to 'String')
-- string :: (MonadThrow m, Show k, Typeable k, GT.TrieKey k, Alternative m) =>
--           k -> D.Decode m (Row k VP) String
-- string k = lookupColM k >>> stringM

-- -- | Lookup and decode a one-hot encoded enum
-- oneHot :: (MonadThrow m, Show k, Typeable k, GT.TrieKey k) =>
--           k -> D.Decode m (Row k VP) (OneHot Int)
-- oneHot k = lookupColM k >>> oneHotM




-- -- spork k1 k2 = (>) <$> real k1 <*> real k2