{-# LANGUAGE TypeFamilies #-}
-- |
-- More generic version of function from "Data.Vector.Fixed"
-- module. They do not require that all vector have same type, only
-- same length. All such functions have suffix /G/.
module Data.Vector.Fixed.Generic (
    -- * Mapping
    mapG
  , imapG
  , mapMG
  , imapMG
    -- * Zips
  , zipWithG
  , izipWithG
  , zipWithMG
  , izipWithMG
  ) where

import Control.Monad (liftM)
import           Data.Vector.Fixed.Cont (Vector,Dim)
import qualified Data.Vector.Fixed.Cont as C



-- | Map over vector
mapG :: (Vector v a, Vector w b, Dim v ~ Dim w)
     => (a -> b) -> v a -> w b
{-# INLINE mapG #-}
mapG :: (a -> b) -> v a -> w b
mapG a -> b
f = ContVec (Dim w) b -> w b
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
ContVec n a -> v a
C.vector
       (ContVec (Dim w) b -> w b)
-> (v a -> ContVec (Dim w) b) -> v a -> w b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> ContVec (Dim w) a -> ContVec (Dim w) b
forall (n :: Nat) a b.
Arity n =>
(a -> b) -> ContVec n a -> ContVec n b
C.map a -> b
f
       (ContVec (Dim w) a -> ContVec (Dim w) b)
-> (v a -> ContVec (Dim w) a) -> v a -> ContVec (Dim w) b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v a -> ContVec (Dim w) a
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
v a -> ContVec n a
C.cvec

-- | Apply function to every element of the vector and its index.
imapG :: (Vector v a, Vector w b, Dim v ~ Dim w)
      => (Int -> a -> b) -> v a -> w b
{-# INLINE imapG #-}
imapG :: (Int -> a -> b) -> v a -> w b
imapG Int -> a -> b
f = ContVec (Dim w) b -> w b
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
ContVec n a -> v a
C.vector
        (ContVec (Dim w) b -> w b)
-> (v a -> ContVec (Dim w) b) -> v a -> w b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> a -> b) -> ContVec (Dim w) a -> ContVec (Dim w) b
forall (n :: Nat) a b.
Arity n =>
(Int -> a -> b) -> ContVec n a -> ContVec n b
C.imap Int -> a -> b
f
        (ContVec (Dim w) a -> ContVec (Dim w) b)
-> (v a -> ContVec (Dim w) a) -> v a -> ContVec (Dim w) b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v a -> ContVec (Dim w) a
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
v a -> ContVec n a
C.cvec

-- | Monadic map over vector.
mapMG :: (Vector v a, Vector w b, Dim w ~ Dim v, Monad m)
      => (a -> m b) -> v a -> m (w b)
{-# INLINE mapMG #-}
mapMG :: (a -> m b) -> v a -> m (w b)
mapMG a -> m b
f = (ContVec (Dim v) b -> w b) -> m (ContVec (Dim v) b) -> m (w b)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ContVec (Dim v) b -> w b
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
ContVec n a -> v a
C.vector
       (m (ContVec (Dim v) b) -> m (w b))
-> (v a -> m (ContVec (Dim v) b)) -> v a -> m (w b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> m b) -> ContVec (Dim v) a -> m (ContVec (Dim v) b)
forall (n :: Nat) (f :: * -> *) a b.
(Arity n, Applicative f) =>
(a -> f b) -> ContVec n a -> f (ContVec n b)
C.mapM a -> m b
f
       (ContVec (Dim v) a -> m (ContVec (Dim v) b))
-> (v a -> ContVec (Dim v) a) -> v a -> m (ContVec (Dim v) b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v a -> ContVec (Dim v) a
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
v a -> ContVec n a
C.cvec

-- | Monadic map over vector.
imapMG :: (Vector v a, Vector w b, Dim w ~ Dim v, Monad m)
       => (Int -> a -> m b) -> v a -> m (w b)
{-# INLINE imapMG #-}
imapMG :: (Int -> a -> m b) -> v a -> m (w b)
imapMG Int -> a -> m b
f = (ContVec (Dim v) b -> w b) -> m (ContVec (Dim v) b) -> m (w b)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ContVec (Dim v) b -> w b
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
ContVec n a -> v a
C.vector
         (m (ContVec (Dim v) b) -> m (w b))
-> (v a -> m (ContVec (Dim v) b)) -> v a -> m (w b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> a -> m b) -> ContVec (Dim v) a -> m (ContVec (Dim v) b)
forall (n :: Nat) (f :: * -> *) a b.
(Arity n, Applicative f) =>
(Int -> a -> f b) -> ContVec n a -> f (ContVec n b)
C.imapM Int -> a -> m b
f
         (ContVec (Dim v) a -> m (ContVec (Dim v) b))
-> (v a -> ContVec (Dim v) a) -> v a -> m (ContVec (Dim v) b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v a -> ContVec (Dim v) a
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
v a -> ContVec n a
C.cvec


-- | Zip two vector together using function.
zipWithG :: (Vector v a, Vector w b, Vector u c, Dim v ~ Dim u, Dim v ~ Dim w)
         => (a -> b -> c) -> v a -> w b -> u c
{-# INLINE zipWithG #-}
zipWithG :: (a -> b -> c) -> v a -> w b -> u c
zipWithG a -> b -> c
f v a
v w b
u = ContVec (Dim u) c -> u c
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
ContVec n a -> v a
C.vector
               (ContVec (Dim u) c -> u c) -> ContVec (Dim u) c -> u c
forall a b. (a -> b) -> a -> b
$ (a -> b -> c)
-> ContVec (Dim u) a -> ContVec (Dim u) b -> ContVec (Dim u) c
forall (n :: Nat) a b c.
Arity n =>
(a -> b -> c) -> ContVec n a -> ContVec n b -> ContVec n c
C.zipWith a -> b -> c
f (v a -> ContVec (Dim u) a
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
v a -> ContVec n a
C.cvec v a
v) (w b -> ContVec (Dim u) b
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
v a -> ContVec n a
C.cvec w b
u)

-- | Zip two vector together using monadic function.
zipWithMG :: (Vector v a, Vector w b, Vector u c, Dim v ~ Dim u, Dim v ~ Dim w, Monad m)
          => (a -> b -> m c) -> v a -> w b -> m (u c)
{-# INLINE zipWithMG #-}
zipWithMG :: (a -> b -> m c) -> v a -> w b -> m (u c)
zipWithMG a -> b -> m c
f v a
v w b
u = (ContVec (Dim u) c -> u c) -> m (ContVec (Dim u) c) -> m (u c)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ContVec (Dim u) c -> u c
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
ContVec n a -> v a
C.vector
                (m (ContVec (Dim u) c) -> m (u c))
-> m (ContVec (Dim u) c) -> m (u c)
forall a b. (a -> b) -> a -> b
$ (a -> b -> m c)
-> ContVec (Dim u) a -> ContVec (Dim u) b -> m (ContVec (Dim u) c)
forall (n :: Nat) (f :: * -> *) a b c.
(Arity n, Applicative f) =>
(a -> b -> f c) -> ContVec n a -> ContVec n b -> f (ContVec n c)
C.zipWithM a -> b -> m c
f (v a -> ContVec (Dim u) a
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
v a -> ContVec n a
C.cvec v a
v) (w b -> ContVec (Dim u) b
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
v a -> ContVec n a
C.cvec w b
u)

-- | Zip two vector together using function which takes element index
--   as well.
izipWithG :: (Vector v a, Vector w b, Vector u c, Dim v ~ Dim u, Dim v ~ Dim w)
          => (Int -> a -> b -> c) -> v a -> w b -> u c
{-# INLINE izipWithG #-}
izipWithG :: (Int -> a -> b -> c) -> v a -> w b -> u c
izipWithG Int -> a -> b -> c
f v a
v w b
u = ContVec (Dim u) c -> u c
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
ContVec n a -> v a
C.vector
                (ContVec (Dim u) c -> u c) -> ContVec (Dim u) c -> u c
forall a b. (a -> b) -> a -> b
$ (Int -> a -> b -> c)
-> ContVec (Dim u) a -> ContVec (Dim u) b -> ContVec (Dim u) c
forall (n :: Nat) a b c.
Arity n =>
(Int -> a -> b -> c) -> ContVec n a -> ContVec n b -> ContVec n c
C.izipWith Int -> a -> b -> c
f (v a -> ContVec (Dim u) a
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
v a -> ContVec n a
C.cvec v a
v) (w b -> ContVec (Dim u) b
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
v a -> ContVec n a
C.cvec w b
u)

-- | Zip two vector together using monadic function which takes element
--   index as well..
izipWithMG :: (Vector v a, Vector w b, Vector u c, Dim v ~ Dim u, Dim v ~ Dim w, Monad m)
           => (Int -> a -> b -> m c) -> v a -> w b -> m (u c)
{-# INLINE izipWithMG #-}
izipWithMG :: (Int -> a -> b -> m c) -> v a -> w b -> m (u c)
izipWithMG Int -> a -> b -> m c
f v a
v w b
u = (ContVec (Dim u) c -> u c) -> m (ContVec (Dim u) c) -> m (u c)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ContVec (Dim u) c -> u c
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
ContVec n a -> v a
C.vector
                 (m (ContVec (Dim u) c) -> m (u c))
-> m (ContVec (Dim u) c) -> m (u c)
forall a b. (a -> b) -> a -> b
$ (Int -> a -> b -> m c)
-> ContVec (Dim u) a -> ContVec (Dim u) b -> m (ContVec (Dim u) c)
forall (n :: Nat) (f :: * -> *) a b c.
(Arity n, Applicative f) =>
(Int -> a -> b -> f c)
-> ContVec n a -> ContVec n b -> f (ContVec n c)
C.izipWithM Int -> a -> b -> m c
f (v a -> ContVec (Dim u) a
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
v a -> ContVec n a
C.cvec v a
v) (w b -> ContVec (Dim u) b
forall (v :: * -> *) a (n :: Nat).
(Vector v a, Dim v ~ n) =>
v a -> ContVec n a
C.cvec w b
u)