{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}
module Data.Grid.Internal.NestedLists where
import GHC.TypeNats as N
import Data.Singletons.Prelude
import qualified Data.Vector as V
type family NestedLists (dims :: [Nat]) a where
NestedLists '[] a = a
NestedLists (_:xs) a = [NestedLists xs a]
chunkVector :: forall a . Int -> V.Vector a -> [V.Vector a]
chunkVector n v
| V.null v
= []
| otherwise
= let (before, after) = V.splitAt n v in before : chunkVector n after
class Sizable (dims :: [Nat]) where
nestLists :: Proxy dims -> V.Vector a -> NestedLists dims a
unNestLists :: Proxy dims -> NestedLists dims a -> [a]
gridSize :: Proxy dims -> Int
instance {-# OVERLAPPING #-} KnownNat x => Sizable '[x] where
nestLists _ = V.toList
unNestLists _ xs = xs
gridSize _ = fromIntegral $ natVal (Proxy @x)
instance {-# OVERLAPPABLE #-} (KnownNat x, Sizable (y:xs)) => Sizable (x:y:xs) where
nestLists _ v = nestLists (Proxy @(y:xs)) <$> chunkVector (gridSize $ Proxy @(y:xs)) v
unNestLists _ xs = concat (unNestLists (Proxy @(y:xs)) <$> xs)
gridSize _ = gridSize (Proxy @(y:xs)) * fromIntegral (natVal (Proxy @x))