packages feed

mutable-fenwick-0.1.0.0: src/Data/Vector/VectorC.hs

{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}

-- | Module       : Data.Array.VectorC
-- 
-- This modulo provides 'VectorC' and 'MVectorC', which given a existing vector implementation and a
-- representation type, it stores elements by coercing the element type into representation type.
-- Using this, we can have elements with algebraic structures (like 'Data.Monoid.Monoid' used in
-- this package) but stored in efficient unboxed vectors.
module Data.Vector.VectorC (
  VectorC, MVectorC
) where

import qualified Data.Vector.Generic as VG
import qualified Data.Vector.Generic.Mutable as VGM
import Data.Coerce

-- | Given a mutable vector type @vector@ and representation type @rep@, the type contructor
-- @'MVectorC' vector rep@ is a valid vector type that stores elements that are coercible to @rep@.
-- Use functions in 'Data.Vector.Generic.Mutable.MVector' to create and modify these vectors.
newtype MVectorC vector rep s elem = MVectorC (vector s rep)

-- | Immutable vectors corresponding to 'MVectorC'. Use functions in 'Data.Vector.Generic.Vector' to create and
-- modify these vectors.
newtype VectorC vector rep elem = VectorC (vector rep)

type instance VG.Mutable (VectorC vector rep) = MVectorC (VG.Mutable vector) rep

instance (Coercible elem rep, VGM.MVector vector rep) => VGM.MVector (MVectorC vector rep) elem where
  -- basicLength = coerce $ VGM.basicLength @vector @rep
  basicLength (MVectorC vec) = VGM.basicLength vec
  {-# INLINE basicLength #-}
  -- basicUnsafeSlice = coerce $ VGM.basicUnsafeSlice @VU.MVector
  basicUnsafeSlice i n (MVectorC vec) = MVectorC (VGM.basicUnsafeSlice i n vec)
  {-# INLINE basicUnsafeSlice #-}
  -- basicOverlaps = coerce $ VGM.basicOverlaps @VU.MVector
  basicOverlaps (MVectorC vec1) (MVectorC vec2) = VGM.basicOverlaps vec1 vec2
  {-# INLINE basicOverlaps #-}
  -- basicUnsafeNew = coerce $ VGM.basicUnsafeNew @VU.MVector
  basicUnsafeNew n = MVectorC <$> VGM.basicUnsafeNew n
  {-# INLINE basicUnsafeNew #-}
  -- basicInitialize = coerce $ VGM.basicInitialize @VU.MVector
  basicInitialize (MVectorC vec) = VGM.basicInitialize vec
  {-# INLINE basicInitialize #-}
  -- basicUnsafeReplicate = coerce $ VGM.basicUnsafeReplicate @VU.MVector
  basicUnsafeReplicate n a = MVectorC <$> VGM.basicUnsafeReplicate n (coerce a)
  {-# INLINE basicUnsafeReplicate #-}
  -- basicUnsafeRead = coerce $ VGM.basicUnsafeRead @VU.MVector
  basicUnsafeRead (MVectorC vec) i = coerce <$> VGM.basicUnsafeRead vec i
  {-# INLINE basicUnsafeRead #-}
  -- basicUnsafeWrite = coerce $ VGM.basicUnsafeWrite @VU.MVector
  basicUnsafeWrite (MVectorC vec) i a = VGM.basicUnsafeWrite vec i (coerce a)
  {-# INLINE basicUnsafeWrite #-}
  -- basicClear = coerce $ VGM.basicClear @VU.MVector
  basicClear (MVectorC vec) = VGM.basicClear vec
  {-# INLINE basicClear #-}
  -- basicSet = coerce $ VGM.basicSet @VU.MVector
  basicSet (MVectorC vec) a = VGM.basicSet vec (coerce a)
  {-# INLINE basicSet #-}
  -- basicUnsafeCopy = coerce $ VGM.basicUnsafeCopy @VU.MVector
  basicUnsafeCopy (MVectorC vec1) (MVectorC vec2) = VGM.basicUnsafeCopy vec1 vec2
  {-# INLINE basicUnsafeCopy #-}
  -- basicUnsafeMove = coerce $ VGM.basicUnsafeMove @VU.MVector
  basicUnsafeMove (MVectorC vec1) (MVectorC vec2) = VGM.basicUnsafeMove vec1 vec2
  {-# INLINE basicUnsafeMove #-}
  -- basicUnsafeGrow = coerce $ VGM.basicUnsafeGrow @VU.MVector
  basicUnsafeGrow (MVectorC vec) n = MVectorC <$> VGM.basicUnsafeGrow vec n
  {-# INLINE basicUnsafeGrow #-}

instance (Coercible elem rep, VG.Vector vector rep) => VG.Vector (VectorC vector rep) elem where
  basicUnsafeFreeze = coerce $ VG.basicUnsafeFreeze @vector @rep
  {-# INLINE basicUnsafeFreeze #-}
  basicUnsafeThaw = coerce $ VG.basicUnsafeThaw @vector @rep
  {-# INLINE basicUnsafeThaw #-}
  basicLength = coerce $ VG.basicLength @vector @rep
  {-# INLINE basicLength #-}
  basicUnsafeSlice = coerce $ VG.basicUnsafeSlice @vector @rep
  {-# INLINE basicUnsafeSlice #-}
  basicUnsafeIndexM = coerce $ VG.basicUnsafeIndexM @vector @rep
  {-# INLINE basicUnsafeIndexM #-}
  basicUnsafeCopy = coerce $ VG.basicUnsafeCopy @vector @rep
  {-# INLINE basicUnsafeCopy #-}
  elemseq (VectorC vec) a = VG.elemseq vec (coerce a)
  {-# INLINE elemseq #-}