{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE ScopedTypeVariables #-}

module DSV.Header
  ( zipHeader, zipHeader', zipHeaderPipe
  , zipHeaderWith, zipHeaderWith', zipHeaderWithPipe
  , applyHeaderPipe, applyHeaderPipeM
  ) where

import DSV.Pipes
import DSV.Prelude
import DSV.Vector

-- pipes
import qualified Pipes.Prelude as P

zipHeader :: forall a . [Vector a] -> [Vector (a, a)]
zipHeader :: [Vector a] -> [Vector (a, a)]
zipHeader [] = []
zipHeader (Vector a
names : [Vector a]
rows) = Vector a -> [Vector a] -> [Vector (a, a)]
forall a b. Vector a -> [Vector b] -> [Vector (a, b)]
zipHeader' Vector a
names [Vector a]
rows

zipHeader' :: forall a b . Vector a -> [Vector b] -> [Vector (a, b)]
zipHeader' :: Vector a -> [Vector b] -> [Vector (a, b)]
zipHeader' Vector a
names [Vector b]
rows = (Vector b -> Vector (a, b)) -> [Vector b] -> [Vector (a, b)]
forall a b. (a -> b) -> [a] -> [b]
map (Vector a -> Vector b -> Vector (a, b)
forall a b. Vector a -> Vector b -> Vector (a, b)
vectorZip Vector a
names) [Vector b]
rows

zipHeaderWith :: forall a b . (a -> a -> b) -> [Vector a] -> [Vector b]
zipHeaderWith :: (a -> a -> b) -> [Vector a] -> [Vector b]
zipHeaderWith a -> a -> b
_ [] = []
zipHeaderWith a -> a -> b
f (Vector a
names : [Vector a]
rows) = (a -> a -> b) -> Vector a -> [Vector a] -> [Vector b]
forall a b c. (a -> b -> c) -> Vector a -> [Vector b] -> [Vector c]
zipHeaderWith' a -> a -> b
f Vector a
names [Vector a]
rows

zipHeaderWith' :: forall a b c . (a -> b -> c)
    -> Vector a -> [Vector b] -> [Vector c]
zipHeaderWith' :: (a -> b -> c) -> Vector a -> [Vector b] -> [Vector c]
zipHeaderWith' a -> b -> c
f Vector a
names [Vector b]
rows = (Vector b -> Vector c) -> [Vector b] -> [Vector c]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> b -> c) -> Vector a -> Vector b -> Vector c
forall a b c. (a -> b -> c) -> Vector a -> Vector b -> Vector c
vectorZipWith a -> b -> c
f Vector a
names) [Vector b]
rows

applyHeaderPipe ::
    forall a b m r .
    Monad m
    => (a -> a -> b)
    -> Pipe a b m r

applyHeaderPipe :: (a -> a -> b) -> Pipe a b m r
applyHeaderPipe a -> a -> b
f =
  do
    a
header <- Proxy () a () b m a
forall (m :: * -> *) a. Functor m => Consumer' a m a
await
    (a -> b) -> Pipe a b m r
forall (m :: * -> *) a b r. Functor m => (a -> b) -> Pipe a b m r
P.map (a -> a -> b
f a
header)

applyHeaderPipeM ::
    forall a b m r .
    Monad m
    => (a -> m (a -> m b))
    -> Pipe a b m r

applyHeaderPipeM :: (a -> m (a -> m b)) -> Pipe a b m r
applyHeaderPipeM a -> m (a -> m b)
f =
  do
    a
header <- Proxy () a () b m a
forall (m :: * -> *) a. Functor m => Consumer' a m a
await
    a -> m b
applyHeader <- m (a -> m b) -> Proxy () a () b m (a -> m b)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (a -> m (a -> m b)
f a
header)
    (a -> m b) -> Pipe a b m r
forall (m :: * -> *) a b r. Monad m => (a -> m b) -> Pipe a b m r
P.mapM a -> m b
applyHeader

{- |

=== Example

>>> import qualified Pipes.Prelude as P
>>> r1 = listToVector ["A","B"]
>>> r2 = listToVector ["1","2"]
>>> r3 = listToVector ["3","4"]
>>> p = do { yield r1; yield r2; yield r3 }
>>> runEffect (p >-> zipHeaderPipe >-> P.print)
[("A","1"),("B","2")]
[("A","3"),("B","4")]

-}

zipHeaderPipe ::
    forall a m r .
    Monad m
    => Pipe (Vector a) (Vector (a, a)) m r

zipHeaderPipe :: Pipe (Vector a) (Vector (a, a)) m r
zipHeaderPipe = (Vector a -> Vector a -> Vector (a, a))
-> Pipe (Vector a) (Vector (a, a)) m r
forall a b (m :: * -> *) r.
Monad m =>
(a -> a -> b) -> Pipe a b m r
applyHeaderPipe Vector a -> Vector a -> Vector (a, a)
forall a b. Vector a -> Vector b -> Vector (a, b)
vectorZip

{- |

=== Example

>>> import qualified Pipes.Prelude as P
>>> r1 = listToVector ["A","B"]
>>> r2 = listToVector ["1","2"]
>>> r3 = listToVector ["3","4"]
>>> p = do { yield r1; yield r2; yield r3 }
>>> runEffect (p >-> zipHeaderWithPipe (<>) >-> P.print)
["A1","B2"]
["A3","B4"]

-}

zipHeaderWithPipe ::
    forall a b m r .
    Monad m
    => (a -> a -> b)
    -> Pipe (Vector a) (Vector b) m r

zipHeaderWithPipe :: (a -> a -> b) -> Pipe (Vector a) (Vector b) m r
zipHeaderWithPipe a -> a -> b
f = (Vector a -> Vector a -> Vector b)
-> Pipe (Vector a) (Vector b) m r
forall a b (m :: * -> *) r.
Monad m =>
(a -> a -> b) -> Pipe a b m r
applyHeaderPipe ((a -> a -> b) -> Vector a -> Vector a -> Vector b
forall a b c. (a -> b -> c) -> Vector a -> Vector b -> Vector c
vectorZipWith a -> a -> b
f)