module Data.PrimitiveArray.Index.PhantomInt where
import Control.DeepSeq (NFData(..))
import Data.Aeson (FromJSON,FromJSONKey,ToJSON,ToJSONKey)
import Data.Binary (Binary)
import Data.Data
import Data.Hashable (Hashable)
import Data.Ix(Ix)
import Data.Serialize (Serialize)
import Data.Typeable
import Data.Vector.Fusion.Stream.Monadic (map,Step(..),flatten)
import Data.Vector.Unboxed.Deriving
import GHC.Generics (Generic)
import Prelude hiding (map)
import Data.PrimitiveArray.Index.Class
import Data.PrimitiveArray.Index.IOC
newtype PInt (ioc ∷ k) (p ∷ k) = PInt { getPInt :: Int }
deriving (Read,Show,Eq,Ord,Enum,Num,Integral,Real,Generic,Data,Typeable,Ix)
pIntI :: Int -> PInt I p
pIntI = PInt
{-# Inline pIntI #-}
pIntO :: Int -> PInt O p
pIntO = PInt
{-# Inline pIntO #-}
pIntC :: Int -> PInt C p
pIntC = PInt
{-# Inline pIntC #-}
derivingUnbox "PInt"
[t| forall t p . PInt t p -> Int |] [| getPInt |] [| PInt |]
instance Binary (PInt t p)
instance Serialize (PInt t p)
instance FromJSON (PInt t p)
instance FromJSONKey (PInt t p)
instance ToJSON (PInt t p)
instance ToJSONKey (PInt t p)
instance Hashable (PInt t p)
instance NFData (PInt t p)
instance Index (PInt t p) where
newtype LimitType (PInt t p) = LtPInt Int
linearIndex _ (PInt k) = k
{-# Inline linearIndex #-}
size (LtPInt h) = h+1
{-# Inline size #-}
inBounds (LtPInt h) (PInt k) = 0 <= k && k <= h
{-# Inline inBounds #-}
deriving instance Show (LimitType (PInt t p))
deriving instance Read (LimitType (PInt t p))
deriving instance Eq (LimitType (PInt t p))
deriving instance Generic (LimitType (PInt t p))
instance IndexStream z => IndexStream (z:.PInt I p) where
streamUp (ls:..LtPInt l) (hs:..LtPInt h) = flatten (streamUpMk l h) (streamUpStep l h) $ streamUp ls hs
streamDown (ls:..LtPInt l) (hs:..LtPInt h) = flatten (streamDownMk l h) (streamDownStep l h) $ streamDown ls hs
{-# Inline streamUp #-}
{-# Inline streamDown #-}
instance IndexStream z => IndexStream (z:.PInt O p) where
streamUp (ls:..LtPInt l) (hs:..LtPInt h) = flatten (streamDownMk l h) (streamDownStep l h) $ streamUp ls hs
streamDown (ls:..LtPInt l) (hs:..LtPInt h) = flatten (streamUpMk l h) (streamUpStep l h) $ streamDown ls hs
{-# Inline streamUp #-}
{-# Inline streamDown #-}
instance IndexStream z => IndexStream (z:.PInt C p) where
streamUp (ls:..LtPInt l) (hs:..LtPInt h) = flatten (streamUpMk l h) (streamUpStep l h) $ streamUp ls hs
streamDown (ls:..LtPInt l) (hs:..LtPInt h) = flatten (streamDownMk l h) (streamDownStep l h) $ streamDown ls hs
{-# Inline streamUp #-}
{-# Inline streamDown #-}
instance IndexStream (Z:.PInt ioc p) => IndexStream (PInt ioc p) where
streamUp l h = map (\(Z:.i) -> i) $ streamUp (ZZ:..l) (ZZ:..h)
{-# INLINE streamUp #-}
streamDown l h = map (\(Z:.i) -> i) $ streamDown (ZZ:..l) (ZZ:..h)
{-# INLINE streamDown #-}
streamUpMk l h z = return (z,l)
{-# Inline [0] streamUpMk #-}
streamUpStep l h (z,k)
| k > h = return $ Done
| otherwise = return $ Yield (z:.PInt k) (z,k+1)
{-# Inline [0] streamUpStep #-}
streamDownMk l h z = return (z,h)
{-# Inline [0] streamDownMk #-}
streamDownStep l h (z,k)
| k < l = return $ Done
| otherwise = return $ Yield (z:.PInt k) (z,k-1)
{-# Inline [0] streamDownStep #-}