{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE KindSignatures #-}
{-# OPTIONS_HADDOCK not-home #-}
module Data.Vector.Generic.Sized.Internal
( Vector(..)
)
where
import Control.DeepSeq ( NFData )
import Data.Data ( Data
, Typeable
)
import Data.Functor.Classes ( Eq1
, Ord1
, Show1
)
import Data.Vector as V
( and
, foldl'
, null
, zipWith
, zipWith3
)
import qualified Data.Vector.Generic as VG
( Vector
, convert
, empty
, fromList
, toList
)
import GHC.Arr ( Ix
( inRange
, range
, unsafeIndex
, unsafeRangeSize
)
)
import GHC.Generics ( Generic )
import GHC.TypeLits ( Nat )
newtype Vector v (n :: Nat) a = Vector (v a)
deriving ( Show, Eq, Ord, Functor, Foldable, Traversable, NFData, Generic
, Show1, Eq1, Ord1
, Data, Typeable
)
instance (Ix a, Ord (v a), VG.Vector v a) => Ix (Vector v n a) where
range (Vector l, Vector u) = Vector <$> enumerate ranges
where
ranges = V.zipWith (curry range) lc uc
lc = VG.convert l
uc = VG.convert u
enumerate v | V.null v = [VG.empty]
| otherwise = map VG.fromList $ enumerate' (VG.toList v)
enumerate' [] = [[]]
enumerate' (xs : xss) = [ x : xs' | x <- xs, xs' <- enumerate' xss ]
unsafeIndex (Vector l, Vector u) (Vector i) = V.foldl' f 0 v
where
f acc (index', rangeSize') = acc * rangeSize' + index'
v = V.zipWith3 indexAndRangeSize lc uc ic
(lc, uc, ic) = convert3 l u i
indexAndRangeSize l' u' i' =
let b' = (l', u') in (unsafeIndex b' i', unsafeRangeSize b')
inRange (Vector l, Vector u) (Vector i) = V.and
$ V.zipWith3 (curry inRange) lc uc ic
where (lc, uc, ic) = convert3 l u i
{-# INLINE convert3 #-}
convert3
:: ( VG.Vector v1 a
, VG.Vector w1 a
, VG.Vector v2 b
, VG.Vector w2 b
, VG.Vector v3 c
, VG.Vector w3 c
)
=> v1 a
-> v2 b
-> v3 c
-> (w1 a, w2 b, w3 c)
convert3 v1 v2 v3 = (VG.convert v1, VG.convert v2, VG.convert v3)