{-# LANGUAGE AllowAmbiguousTypes   #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}

module HaskellWorks.Data.Vector.BoxedVectorLike
  ( BoxedVectorLike(..)
  ) where

import Data.Word
import Foreign.Storable

import qualified Data.Vector as DV

-- | Class of values that support boxed vector like operations
class BoxedVectorLike v e where
  bImap :: (Int -> a -> b) -> v a -> v b
  bMap :: (a -> b) -> v a -> v b
  bUnfoldr :: (Storable a) => (b -> Maybe (a, b)) -> b -> v a
  bUnfoldrN :: (Storable a) => Int -> (b -> Maybe (a, b)) -> b -> v a

instance BoxedVectorLike DV.Vector Word8 where
  bImap :: (Int -> a -> b) -> Vector a -> Vector b
bImap = (Int -> a -> b) -> Vector a -> Vector b
forall a b. (Int -> a -> b) -> Vector a -> Vector b
DV.imap
  bMap :: (a -> b) -> Vector a -> Vector b
bMap = (a -> b) -> Vector a -> Vector b
forall a b. (a -> b) -> Vector a -> Vector b
DV.map
  bUnfoldr :: (b -> Maybe (a, b)) -> b -> Vector a
bUnfoldr = (b -> Maybe (a, b)) -> b -> Vector a
forall b a. (b -> Maybe (a, b)) -> b -> Vector a
DV.unfoldr
  bUnfoldrN :: Int -> (b -> Maybe (a, b)) -> b -> Vector a
bUnfoldrN = Int -> (b -> Maybe (a, b)) -> b -> Vector a
forall b a. Int -> (b -> Maybe (a, b)) -> b -> Vector a
DV.unfoldrN
  {-# INLINE bImap     #-}
  {-# INLINE bMap      #-}
  {-# INLINE bUnfoldr  #-}
  {-# INLINE bUnfoldrN #-}

instance BoxedVectorLike DV.Vector Word16 where
  bImap :: (Int -> a -> b) -> Vector a -> Vector b
bImap = (Int -> a -> b) -> Vector a -> Vector b
forall a b. (Int -> a -> b) -> Vector a -> Vector b
DV.imap
  bMap :: (a -> b) -> Vector a -> Vector b
bMap = (a -> b) -> Vector a -> Vector b
forall a b. (a -> b) -> Vector a -> Vector b
DV.map
  bUnfoldr :: (b -> Maybe (a, b)) -> b -> Vector a
bUnfoldr = (b -> Maybe (a, b)) -> b -> Vector a
forall b a. (b -> Maybe (a, b)) -> b -> Vector a
DV.unfoldr
  bUnfoldrN :: Int -> (b -> Maybe (a, b)) -> b -> Vector a
bUnfoldrN = Int -> (b -> Maybe (a, b)) -> b -> Vector a
forall b a. Int -> (b -> Maybe (a, b)) -> b -> Vector a
DV.unfoldrN
  {-# INLINE bImap     #-}
  {-# INLINE bMap      #-}
  {-# INLINE bUnfoldr  #-}
  {-# INLINE bUnfoldrN #-}

instance BoxedVectorLike DV.Vector Word32 where
  bImap :: (Int -> a -> b) -> Vector a -> Vector b
bImap = (Int -> a -> b) -> Vector a -> Vector b
forall a b. (Int -> a -> b) -> Vector a -> Vector b
DV.imap
  bMap :: (a -> b) -> Vector a -> Vector b
bMap = (a -> b) -> Vector a -> Vector b
forall a b. (a -> b) -> Vector a -> Vector b
DV.map
  bUnfoldr :: (b -> Maybe (a, b)) -> b -> Vector a
bUnfoldr = (b -> Maybe (a, b)) -> b -> Vector a
forall b a. (b -> Maybe (a, b)) -> b -> Vector a
DV.unfoldr
  bUnfoldrN :: Int -> (b -> Maybe (a, b)) -> b -> Vector a
bUnfoldrN = Int -> (b -> Maybe (a, b)) -> b -> Vector a
forall b a. Int -> (b -> Maybe (a, b)) -> b -> Vector a
DV.unfoldrN
  {-# INLINE bImap     #-}
  {-# INLINE bMap      #-}
  {-# INLINE bUnfoldr  #-}
  {-# INLINE bUnfoldrN #-}

instance BoxedVectorLike DV.Vector Word64 where
  bImap :: (Int -> a -> b) -> Vector a -> Vector b
bImap = (Int -> a -> b) -> Vector a -> Vector b
forall a b. (Int -> a -> b) -> Vector a -> Vector b
DV.imap
  bMap :: (a -> b) -> Vector a -> Vector b
bMap = (a -> b) -> Vector a -> Vector b
forall a b. (a -> b) -> Vector a -> Vector b
DV.map
  bUnfoldr :: (b -> Maybe (a, b)) -> b -> Vector a
bUnfoldr = (b -> Maybe (a, b)) -> b -> Vector a
forall b a. (b -> Maybe (a, b)) -> b -> Vector a
DV.unfoldr
  bUnfoldrN :: Int -> (b -> Maybe (a, b)) -> b -> Vector a
bUnfoldrN = Int -> (b -> Maybe (a, b)) -> b -> Vector a
forall b a. Int -> (b -> Maybe (a, b)) -> b -> Vector a
DV.unfoldrN
  {-# INLINE bImap     #-}
  {-# INLINE bMap      #-}
  {-# INLINE bUnfoldr  #-}
  {-# INLINE bUnfoldrN #-}