{-# language OverloadedStrings #-}
{-# language FlexibleInstances #-}
{-# language DeriveFunctor, DeriveFoldable, DeriveTraversable, GeneralizedNewtypeDeriving #-}
{-# language ConstraintKinds #-}
{-# OPTIONS_GHC -Wno-unused-top-binds #-}
{-# OPTIONS_GHC -Wno-type-defaults #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Core.Data.Frame.List
-- Description :  List-based dataframe
-- Copyright   :  (c) Marco Zocca (2018-2019)
-- License     :  BSD-style
-- Maintainer  :  ocramz fripost org
-- Stability   :  experimental
-- Portability :  GHC
--
-- A general-purpose, row-oriented data frame, encoded as a list of rows
--
-----------------------------------------------------------------------------
module Core.Data.Frame.List (
  -- * Frame
  Frame,
  -- ** Construction
  frameFromList,
  -- ** Access
  Core.Data.Frame.List.head,
  Core.Data.Frame.List.take,
  Core.Data.Frame.List.drop, Core.Data.Frame.List.zipWith, numRows, 
  -- ** Filtering 
  Core.Data.Frame.List.filter, 
  -- *** 'D.Decode'-based filtering helpers
  filterA, 
  -- **
  groupWith, 
  -- ** Scans (row-wise cumulative operations)
  Core.Data.Frame.List.scanl, Core.Data.Frame.List.scanr,
  -- ** Vector-related
  toVector, fromVector,
  -- *** Sorting
  ) where

import qualified Control.Monad as CM (filterM)
import Data.List (groupBy)

import qualified Data.Vector as V


-- | A 'Frame' is a list of rows.
newtype Frame row = Frame {
    Frame row -> [row]
tableRows :: [row] } deriving (Int -> Frame row -> ShowS
[Frame row] -> ShowS
Frame row -> String
(Int -> Frame row -> ShowS)
-> (Frame row -> String)
-> ([Frame row] -> ShowS)
-> Show (Frame row)
forall row. Show row => Int -> Frame row -> ShowS
forall row. Show row => [Frame row] -> ShowS
forall row. Show row => Frame row -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Frame row] -> ShowS
$cshowList :: forall row. Show row => [Frame row] -> ShowS
show :: Frame row -> String
$cshow :: forall row. Show row => Frame row -> String
showsPrec :: Int -> Frame row -> ShowS
$cshowsPrec :: forall row. Show row => Int -> Frame row -> ShowS
Show, a -> Frame b -> Frame a
(a -> b) -> Frame a -> Frame b
(forall a b. (a -> b) -> Frame a -> Frame b)
-> (forall a b. a -> Frame b -> Frame a) -> Functor Frame
forall a b. a -> Frame b -> Frame a
forall a b. (a -> b) -> Frame a -> Frame b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Frame b -> Frame a
$c<$ :: forall a b. a -> Frame b -> Frame a
fmap :: (a -> b) -> Frame a -> Frame b
$cfmap :: forall a b. (a -> b) -> Frame a -> Frame b
Functor, a -> Frame a -> Bool
Frame m -> m
Frame a -> [a]
Frame a -> Bool
Frame a -> Int
Frame a -> a
Frame a -> a
Frame a -> a
Frame a -> a
(a -> m) -> Frame a -> m
(a -> m) -> Frame a -> m
(a -> b -> b) -> b -> Frame a -> b
(a -> b -> b) -> b -> Frame a -> b
(b -> a -> b) -> b -> Frame a -> b
(b -> a -> b) -> b -> Frame a -> b
(a -> a -> a) -> Frame a -> a
(a -> a -> a) -> Frame a -> a
(forall m. Monoid m => Frame m -> m)
-> (forall m a. Monoid m => (a -> m) -> Frame a -> m)
-> (forall m a. Monoid m => (a -> m) -> Frame a -> m)
-> (forall a b. (a -> b -> b) -> b -> Frame a -> b)
-> (forall a b. (a -> b -> b) -> b -> Frame a -> b)
-> (forall b a. (b -> a -> b) -> b -> Frame a -> b)
-> (forall b a. (b -> a -> b) -> b -> Frame a -> b)
-> (forall a. (a -> a -> a) -> Frame a -> a)
-> (forall a. (a -> a -> a) -> Frame a -> a)
-> (forall a. Frame a -> [a])
-> (forall a. Frame a -> Bool)
-> (forall a. Frame a -> Int)
-> (forall a. Eq a => a -> Frame a -> Bool)
-> (forall a. Ord a => Frame a -> a)
-> (forall a. Ord a => Frame a -> a)
-> (forall a. Num a => Frame a -> a)
-> (forall a. Num a => Frame a -> a)
-> Foldable Frame
forall a. Eq a => a -> Frame a -> Bool
forall a. Num a => Frame a -> a
forall a. Ord a => Frame a -> a
forall m. Monoid m => Frame m -> m
forall a. Frame a -> Bool
forall a. Frame a -> Int
forall a. Frame a -> [a]
forall a. (a -> a -> a) -> Frame a -> a
forall m a. Monoid m => (a -> m) -> Frame a -> m
forall b a. (b -> a -> b) -> b -> Frame a -> b
forall a b. (a -> b -> b) -> b -> Frame 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 :: Frame a -> a
$cproduct :: forall a. Num a => Frame a -> a
sum :: Frame a -> a
$csum :: forall a. Num a => Frame a -> a
minimum :: Frame a -> a
$cminimum :: forall a. Ord a => Frame a -> a
maximum :: Frame a -> a
$cmaximum :: forall a. Ord a => Frame a -> a
elem :: a -> Frame a -> Bool
$celem :: forall a. Eq a => a -> Frame a -> Bool
length :: Frame a -> Int
$clength :: forall a. Frame a -> Int
null :: Frame a -> Bool
$cnull :: forall a. Frame a -> Bool
toList :: Frame a -> [a]
$ctoList :: forall a. Frame a -> [a]
foldl1 :: (a -> a -> a) -> Frame a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Frame a -> a
foldr1 :: (a -> a -> a) -> Frame a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Frame a -> a
foldl' :: (b -> a -> b) -> b -> Frame a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Frame a -> b
foldl :: (b -> a -> b) -> b -> Frame a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Frame a -> b
foldr' :: (a -> b -> b) -> b -> Frame a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Frame a -> b
foldr :: (a -> b -> b) -> b -> Frame a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Frame a -> b
foldMap' :: (a -> m) -> Frame a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Frame a -> m
foldMap :: (a -> m) -> Frame a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Frame a -> m
fold :: Frame m -> m
$cfold :: forall m. Monoid m => Frame m -> m
Foldable, Functor Frame
Foldable Frame
Functor Frame
-> Foldable Frame
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Frame a -> f (Frame b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Frame (f a) -> f (Frame a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Frame a -> m (Frame b))
-> (forall (m :: * -> *) a. Monad m => Frame (m a) -> m (Frame a))
-> Traversable Frame
(a -> f b) -> Frame a -> f (Frame 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 => Frame (m a) -> m (Frame a)
forall (f :: * -> *) a. Applicative f => Frame (f a) -> f (Frame a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Frame a -> m (Frame b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Frame a -> f (Frame b)
sequence :: Frame (m a) -> m (Frame a)
$csequence :: forall (m :: * -> *) a. Monad m => Frame (m a) -> m (Frame a)
mapM :: (a -> m b) -> Frame a -> m (Frame b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Frame a -> m (Frame b)
sequenceA :: Frame (f a) -> f (Frame a)
$csequenceA :: forall (f :: * -> *) a. Applicative f => Frame (f a) -> f (Frame a)
traverse :: (a -> f b) -> Frame a -> f (Frame b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Frame a -> f (Frame b)
$cp2Traversable :: Foldable Frame
$cp1Traversable :: Functor Frame
Traversable)

head :: Frame row -> row
head :: Frame row -> row
head = [row] -> row
forall a. [a] -> a
Prelude.head ([row] -> row) -> (Frame row -> [row]) -> Frame row -> row
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Frame row -> [row]
forall a. Frame a -> [a]
tableRows

-- | Retain n rows
take :: Int -> Frame row -> Frame row
take :: Int -> Frame row -> Frame row
take Int
n = [row] -> Frame row
forall row. [row] -> Frame row
Frame ([row] -> Frame row)
-> (Frame row -> [row]) -> Frame row -> Frame row
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [row] -> [row]
forall a. Int -> [a] -> [a]
Prelude.take Int
n ([row] -> [row]) -> (Frame row -> [row]) -> Frame row -> [row]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Frame row -> [row]
forall a. Frame a -> [a]
tableRows

-- | Drop n rows
drop :: Int -> Frame row -> Frame row
drop :: Int -> Frame row -> Frame row
drop Int
n = [row] -> Frame row
forall row. [row] -> Frame row
Frame ([row] -> Frame row)
-> (Frame row -> [row]) -> Frame row -> Frame row
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [row] -> [row]
forall a. Int -> [a] -> [a]
Prelude.drop Int
n ([row] -> [row]) -> (Frame row -> [row]) -> Frame row -> [row]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Frame row -> [row]
forall a. Frame a -> [a]
tableRows

zipWith :: (a -> b -> c) -> Frame a -> Frame b -> Frame c
zipWith :: (a -> b -> c) -> Frame a -> Frame b -> Frame c
zipWith a -> b -> c
f Frame a
x Frame b
y = [c] -> Frame c
forall row. [row] -> Frame row
frameFromList ([c] -> Frame c) -> [c] -> Frame c
forall a b. (a -> b) -> a -> b
$ (a -> b -> c) -> [a] -> [b] -> [c]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
Prelude.zipWith a -> b -> c
f (Frame a -> [a]
forall a. Frame a -> [a]
tableRows Frame a
x) (Frame b -> [b]
forall a. Frame a -> [a]
tableRows Frame b
y)

frameFromList :: [row] -> Frame row
frameFromList :: [row] -> Frame row
frameFromList = [row] -> Frame row
forall row. [row] -> Frame row
Frame

toList :: Frame row -> [row]
toList :: Frame row -> [row]
toList = Frame row -> [row]
forall a. Frame a -> [a]
tableRows

numRows :: Frame row -> Int
numRows :: Frame row -> Int
numRows = [row] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([row] -> Int) -> (Frame row -> [row]) -> Frame row -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Frame row -> [row]
forall a. Frame a -> [a]
tableRows

filter :: (row -> Bool) -> Frame row -> Frame row
filter :: (row -> Bool) -> Frame row -> Frame row
filter row -> Bool
p = [row] -> Frame row
forall row. [row] -> Frame row
Frame ([row] -> Frame row)
-> (Frame row -> [row]) -> Frame row -> Frame row
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (row -> Bool) -> [row] -> [row]
forall a. (a -> Bool) -> [a] -> [a]
Prelude.filter row -> Bool
p ([row] -> [row]) -> (Frame row -> [row]) -> Frame row -> [row]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Frame row -> [row]
forall a. Frame a -> [a]
tableRows


-- | This generalizes the list-based 'filter' function.
filterA :: Applicative f =>
           (row -> f Bool) -> Frame row -> f (Frame row)
filterA :: (row -> f Bool) -> Frame row -> f (Frame row)
filterA row -> f Bool
fm Frame row
t = [row] -> Frame row
forall row. [row] -> Frame row
frameFromList ([row] -> Frame row) -> f [row] -> f (Frame row)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (row -> f Bool) -> [row] -> f [row]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
CM.filterM row -> f Bool
fm (Frame row -> [row]
forall a. Frame a -> [a]
toList Frame row
t)






-- | Left-associative scan
scanl :: (b -> a -> b) -> b -> Frame a -> Frame b
scanl :: (b -> a -> b) -> b -> Frame a -> Frame b
scanl b -> a -> b
f b
z Frame a
tt = [b] -> Frame b
forall row. [row] -> Frame row
Frame ([b] -> Frame b) -> [b] -> Frame b
forall a b. (a -> b) -> a -> b
$ (b -> a -> b) -> b -> [a] -> [b]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
Prelude.scanl b -> a -> b
f b
z (Frame a -> [a]
forall a. Frame a -> [a]
tableRows Frame a
tt)

-- | Right-associative scan
scanr :: (a -> b -> b) -> b -> Frame a -> Frame b
scanr :: (a -> b -> b) -> b -> Frame a -> Frame b
scanr a -> b -> b
f b
z Frame a
tt = [b] -> Frame b
forall row. [row] -> Frame row
Frame ([b] -> Frame b) -> [b] -> Frame b
forall a b. (a -> b) -> a -> b
$ (a -> b -> b) -> b -> [a] -> [b]
forall a b. (a -> b -> b) -> b -> [a] -> [b]
Prelude.scanr a -> b -> b
f b
z (Frame a -> [a]
forall a. Frame a -> [a]
tableRows Frame a
tt)

-- | 'groupWith' takes row comparison function and a list and returns a list of lists such that the concatenation of the result is equal to the argument. Moreover, each sublist in the result contains only elements that satisfy the comparison. 
groupWith :: (row -> row -> Bool) -> Frame row -> [Frame row]
groupWith :: (row -> row -> Bool) -> Frame row -> [Frame row]
groupWith row -> row -> Bool
f Frame row
t = [row] -> Frame row
forall row. [row] -> Frame row
Frame ([row] -> Frame row) -> [[row]] -> [Frame row]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (row -> row -> Bool) -> [row] -> [[row]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy row -> row -> Bool
f (Frame row -> [row]
forall a. Frame a -> [a]
tableRows Frame row
t)




-- | Produce a 'Vector' of rows
toVector :: Frame row -> V.Vector row
toVector :: Frame row -> Vector row
toVector = [row] -> Vector row
forall a. [a] -> Vector a
V.fromList ([row] -> Vector row)
-> (Frame row -> [row]) -> Frame row -> Vector row
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Frame row -> [row]
forall a. Frame a -> [a]
tableRows

-- | Produce a Frame from a 'Vector' of rows
fromVector :: V.Vector row -> Frame row
fromVector :: Vector row -> Frame row
fromVector = [row] -> Frame row
forall row. [row] -> Frame row
frameFromList ([row] -> Frame row)
-> (Vector row -> [row]) -> Vector row -> Frame row
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector row -> [row]
forall a. Vector a -> [a]
V.toList