packages feed

comfort-array-shape-0.0: src/Data/Array/Comfort/Shape/Static.hs

{-# LANGUAGE TypeFamilies #-}
module Data.Array.Comfort.Shape.Static where

import qualified Data.FixedLength as FL

import qualified Data.Array.Comfort.Storable as Array
import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Storable (Array)

import qualified Type.Data.Num.Unary as Unary
import Type.Data.Num (integralFromProxy)
import Type.Base.Proxy (Proxy(Proxy))

import Foreign.Storable (Storable)


{- $setup
>>> import qualified Data.Array.Comfort.Shape.Static as Static
>>> import qualified Data.Array.Comfort.Shape as Shape
>>>
>>> import qualified Type.Data.Num.Unary.Literal as TypeNum
>>> import qualified Type.Data.Num.Unary as Unary
-}


{- |
'ZeroBased' denotes a range starting at zero and has a certain length.

>>> Shape.indices (Static.ZeroBased (Unary.unary TypeNum.u0))
[]
>>> Shape.indices (Static.ZeroBased (Unary.unary TypeNum.u1))
[i0]
>>> Shape.indices (Static.ZeroBased (Unary.unary TypeNum.u7))
[i0,i1,i2,i3,i4,i5,i6]
-}
newtype ZeroBased n = ZeroBased {zeroBasedSize :: Proxy (Unary.Un n)}
   deriving (Eq, Show)

instance (Unary.Natural n) => Shape.C (ZeroBased n) where
   size (ZeroBased len) = integralFromProxy len

instance (Unary.Natural n) => Shape.Indexed (ZeroBased n) where
   type Index (ZeroBased n) = FL.Index n
   indices _len = FL.toList FL.indices
   unifiedOffset _len = return . fromIntegral . FL.numFromIndex
   inBounds _len _ix = True

instance (Unary.Natural n) => Shape.InvIndexed (ZeroBased n) where
   -- could be implemented using new fixed-length-0.2.1:FL.indexFromNum
   unifiedIndexFromOffset len k =
      case (0<=k, drop k $ Shape.indices len) of
         (True, i:_) -> return i
         _ ->
            Shape.throwOrError $
            Shape.messageIndexFromOffset "ShapeStatic.ZeroBased" k

instance (Unary.Natural n) => Shape.Static (ZeroBased n) where
   static = ZeroBased Proxy


vector :: (Unary.Natural n, Storable a) => FL.T n a -> Array (ZeroBased n) a
vector = Array.fromList (ZeroBased Proxy) . FL.toList