futhask-base-0.1.0.0: src/Futhask/Array/Rank.hs
{-# LANGUAGE RankNTypes, ExistentialQuantification, FlexibleInstances, UndecidableInstances, TypeFamilyDependencies, MultiParamTypeClasses, ScopedTypeVariables, FlexibleContexts, FunctionalDependencies, ConstraintKinds, QuantifiedConstraints, TypeOperators #-}
module Futhask.Array.Rank where
import Data.Int
import Foreign.Ptr
import Foreign.Storable
import System.IO.Unsafe
class Dim r where
type Size r = res | res -> r
type Index r = res | res -> r
type DimFun r a = res | res -> r
type List r a
sizeAsArgs :: DimFun r a -> Size r -> IO a
sizeFromPointer :: Ptr Int64 -> IO (Size r)
inBounds :: Size r -> Index r -> Bool
linearSize :: Size r -> Int
linearIndex :: Size r -> Index r -> Int
sizeString :: Size r -> String
indexString :: Index r -> String
indices :: Size r -> [Index r]
mapToList :: (Index r -> a) -> Size r -> List r a
ifInBounds s i a = if inBounds s i
then a
else error ("Index " ++ indexString i ++ " out of bounds of array with size " ++ sizeString s ++ ".")
maybeInBounds s i a = if inBounds s i then Just a else Nothing
data R0
data R1
data R2
data R3
data R4
--data Rx
---- recursive indextype
--instance (Dim R) => Rx R
-- type Size (Rx R) = (Int, Size R)
-- type Index (Rx R) = (Int, Index R)
-- inBounds =
-- linearSize
-- linearIndex
instance Dim R0 where
type Size R0 = ()
type Index R0 = ()
type DimFun R0 a = IO a
type List R0 a = a
sizeAsArgs df s = df
sizeFromPointer _ = return ()
inBounds _ _ = True
linearSize _ = 1
linearIndex _ _ = 0
sizeString s = "()"
indexString i = "()"
indices s = [()]
mapToList f s = f ()
instance Dim R1 where
type Size R1 = Int
type Index R1 = Int
type DimFun R1 a = Int64 -> IO a
type List R1 a = [a]
sizeAsArgs df s = df (fromIntegral s)
sizeFromPointer p = fmap fromIntegral (peek p)
inBounds s i = 0 <= i && i < s
linearSize s = s
linearIndex _ i = i
sizeString s = show s
indexString i = show i
indices s = [0..s-1]
mapToList f s = map f [0..s-1]
instance Dim R2 where
type Size R2 = (Int, Int)
type Index R2 = (Int, Int)
type DimFun R2 a = Int64 -> Int64 -> IO a
type List R2 a = [[a]]
sizeAsArgs df (s0, s1) = df (fromIntegral s0) (fromIntegral s1)
sizeFromPointer p = do
s0 <- fmap fromIntegral (peekElemOff p 0)
s1 <- fmap fromIntegral (peekElemOff p 1)
return (s0, s1)
inBounds (s0, s1) (i0, i1) = inBounds s0 i0 && inBounds s1 i1
linearSize (s0, s1) = linearSize s0 * s1
linearIndex (s0, s1) (i0, i1) = linearIndex s0 i0 * s1 + i1
sizeString s = show s
indexString i = show i
indices (s0, s1) = (,) <$> [0..s0-1] <*> [0..s1-1]
mapToList f (s0, s1) = map (\i0 -> map (\i1 -> f (i0, i1))[0..s1-1]) [0..s0-1]
instance Dim R3 where
type Size R3 = (Int, Int, Int)
type Index R3 = (Int, Int, Int)
type DimFun R3 a = Int64 -> Int64 -> Int64 -> IO a
type List R3 a = [[[a]]]
sizeAsArgs df (s0, s1, s2) = df (fromIntegral s0) (fromIntegral s1) (fromIntegral s2)
sizeFromPointer p = do
s0 <- fmap fromIntegral (peekElemOff p 0)
s1 <- fmap fromIntegral (peekElemOff p 1)
s2 <- fmap fromIntegral (peekElemOff p 2)
return (s0, s1, s2)
inBounds (s0, s1, s2) (i0, i1, i2) = inBounds (s0, s1) (i0, i1) && inBounds s2 i2
linearSize (s0, s1, s2) = linearSize (s0, s1) * s2
linearIndex (s0, s1, s2) (i0, i1, i2) = linearIndex (s0, s1) (i0, i1) * s2 + i2
sizeString s = show s
indexString i = show i
indices (s0, s1, s2) = (,,) <$> [0..s0-1] <*> [0..s1-1] <*> [0..s2-1]
mapToList f (s0, s1, s2) =
map (\i0 ->
map (\i1 ->
map (\i2 -> f (i0, i1, i2))
[0..s2-1])
[0..s1-1])
[0..s0-1]
instance Dim R4 where
type Size R4 = (Int, Int, Int, Int)
type Index R4 = (Int, Int, Int, Int)
type DimFun R4 a = Int64 -> Int64 -> Int64 -> Int64 -> IO a
type List R4 a = [[[[a]]]]
sizeAsArgs df (s0, s1, s2, s3) = df (fromIntegral s0) (fromIntegral s1) (fromIntegral s2) (fromIntegral s3)
sizeFromPointer p = do
s0 <- fmap fromIntegral (peekElemOff p 0)
s1 <- fmap fromIntegral (peekElemOff p 1)
s2 <- fmap fromIntegral (peekElemOff p 2)
s3 <- fmap fromIntegral (peekElemOff p 3)
return (s0, s1, s2, s3)
inBounds (s0, s1, s2, s3) (i0, i1, i2, i3) = inBounds (s0, s1, s2) (i0, i1, i2) && inBounds s3 i3
linearSize (s0, s1, s2, s3) = s0 * s1 * s2 * s3
linearIndex (s0, s1, s2, s3) (i0, i1, i2, i3) = linearIndex (s0, s1, s2) (i0, i1, i2) * s3 + i3
sizeString s = show s
indexString i = show i
indices (s0, s1, s2, s3) = (,,,) <$> [0..s0-1] <*> [0..s1-1] <*> [0..s2-1] <*> [0..s3-1]
mapToList f (s0, s1, s2, s3) =
map (\i0 ->
map (\i1 ->
map (\i2 ->
map (\i3 -> f (i0, i1, i2, i3))
[0..s3-1])
[0..s2-1])
[0..s1-1])
[0..s0-1]
--class (Dim (Rank a)) => Indexable a where
-- type Rank a
-- size :: a -> Size (Rank a)
class (Dim (Rank a)) => Array a where
type Rank a
type Elem a
type Mutable a = res | res -> a
size :: a -> Size (Rank a)
mutSize :: Mutable a -> Size (Rank a)
readElem' :: a -> Index (Rank a) -> Elem a
peekElem' :: Mutable a -> Index (Rank a) -> IO (Elem a)
pokeElem' :: Mutable a -> Index (Rank a) -> Elem a -> IO ()
copy :: Mutable a -> IO (Mutable a)
unsafeThaw :: a -> IO (Mutable a)
unsafeFreeze :: Mutable a -> IO a
scratch :: Size (Rank a) -> IO (Mutable a)