grids 0.4.0.0 → 0.5.0.0
raw patch · 13 files changed
+137/−139 lines, 13 filesdep −bifunctorsPVP ok
version bump matches the API change (PVP)
Dependencies removed: bifunctors
API changes (from Hackage documentation)
- Data.Grid: class (AllC KnownNat dims, SingI dims, Enum (Coord dims), Bounded (Coord dims)) => Dimensions (dims :: [Nat])
- Data.Grid.Internal.Convolution: instance (GHC.TypeNats.KnownNat n, Data.Grid.Internal.Convolution.Neighboring ns) => Data.Grid.Internal.Convolution.Neighboring (n : ns)
- Data.Grid.Internal.Convolution: instance GHC.TypeNats.KnownNat n => Data.Grid.Internal.Convolution.Neighboring '[n]
- Data.Grid.Internal.Coord: gridSize :: forall (dims :: [Nat]). SingI dims => Int
- Data.Grid.Internal.Coord: instance (GHC.TypeNats.KnownNat x, GHC.TypeNats.KnownNat y, Data.Singletons.Internal.SingI rest, GHC.Enum.Bounded (Data.Grid.Internal.Coord.Coord rest), GHC.Enum.Enum (Data.Grid.Internal.Coord.Coord (y : rest))) => GHC.Enum.Enum (Data.Grid.Internal.Coord.Coord (x : y : rest))
- Data.Grid.Internal.Grid: class (AllC KnownNat dims, SingI dims, Enum (Coord dims), Bounded (Coord dims)) => Dimensions (dims :: [Nat])
- Data.Grid.Internal.Grid: instance (Data.Grid.Internal.NestedLists.Dimensions dims, GHC.Base.Monoid a) => GHC.Base.Monoid (Data.Grid.Internal.Grid.Grid dims a)
- Data.Grid.Internal.Grid: instance (Data.Grid.Internal.NestedLists.Dimensions dims, GHC.Base.Semigroup a) => GHC.Base.Semigroup (Data.Grid.Internal.Grid.Grid dims a)
- Data.Grid.Internal.Grid: instance (Data.Grid.Internal.Pretty.PrettyList (Data.Grid.Internal.NestedLists.NestedLists dims a), Data.Grid.Internal.NestedLists.Dimensions dims, GHC.Show.Show (Data.Grid.Internal.NestedLists.NestedLists dims a)) => GHC.Show.Show (Data.Grid.Internal.Grid.Grid dims a)
- Data.Grid.Internal.Grid: instance (GHC.Num.Num n, Data.Grid.Internal.NestedLists.Dimensions dims) => GHC.Num.Num (Data.Grid.Internal.Grid.Grid dims n)
- Data.Grid.Internal.Grid: instance Data.Grid.Internal.NestedLists.Dimensions dims => Data.Distributive.Distributive (Data.Grid.Internal.Grid.Grid dims)
- Data.Grid.Internal.Grid: instance Data.Grid.Internal.NestedLists.Dimensions dims => Data.Functor.Rep.Representable (Data.Grid.Internal.Grid.Grid dims)
- Data.Grid.Internal.Grid: instance Data.Grid.Internal.NestedLists.Dimensions dims => GHC.Base.Applicative (Data.Grid.Internal.Grid.Grid dims)
- Data.Grid.Internal.Grid: nestLists :: Dimensions dims => Proxy dims -> Vector a -> NestedLists dims a
- Data.Grid.Internal.Grid: unNestLists :: Dimensions dims => Proxy dims -> NestedLists dims a -> [a]
- Data.Grid.Internal.Nest: joinGrid :: Grid dims (Grid ns a) -> Grid (dims ++ ns) a
- Data.Grid.Internal.Nest: splitGrid :: forall outer inner a from. (from ~ (outer ++ inner), Dimensions from, Dimensions inner, Dimensions outer, NestedLists from a ~ NestedLists outer (NestedLists inner a)) => Grid from a -> Grid outer (Grid inner a)
- Data.Grid.Internal.NestedLists: class (AllC KnownNat dims, SingI dims, Enum (Coord dims), Bounded (Coord dims)) => Dimensions (dims :: [Nat])
- Data.Grid.Internal.NestedLists: instance (GHC.TypeNats.KnownNat x, GHC.Enum.Bounded (Data.Grid.Internal.Coord.Coord xs), Data.Singletons.Internal.SingI xs, Data.Grid.Internal.NestedLists.Dimensions (y : xs)) => Data.Grid.Internal.NestedLists.Dimensions (x : y : xs)
- Data.Grid.Internal.NestedLists: instance GHC.TypeNats.KnownNat x => Data.Grid.Internal.NestedLists.Dimensions '[x]
+ Data.Grid: class Sizable (dims :: [Nat])
+ Data.Grid: nestLists :: Sizable dims => Proxy dims -> Vector a -> NestedLists dims a
+ Data.Grid: type IsGrid dims = (AllC KnownNat dims, SingI dims, Sizable dims, Representable (Grid dims), Enum (Coord dims), Bounded (Coord dims), Neighboring dims)
+ Data.Grid: unNestLists :: Sizable dims => Proxy dims -> NestedLists dims a -> [a]
+ Data.Grid.Internal.Coord: instance (GHC.TypeNats.KnownNat x, GHC.TypeNats.KnownNat y, Data.Grid.Internal.NestedLists.Sizable (y : rest), GHC.Enum.Bounded (Data.Grid.Internal.Coord.Coord rest), GHC.Enum.Enum (Data.Grid.Internal.Coord.Coord (y : rest))) => GHC.Enum.Enum (Data.Grid.Internal.Coord.Coord (x : y : rest))
+ Data.Grid.Internal.Grid: class Neighboring dims
+ Data.Grid.Internal.Grid: instance (Data.Grid.Internal.Grid.IsGrid dims, GHC.Base.Monoid a) => GHC.Base.Monoid (Data.Grid.Internal.Grid.Grid dims a)
+ Data.Grid.Internal.Grid: instance (Data.Grid.Internal.Grid.IsGrid dims, GHC.Base.Semigroup a) => GHC.Base.Semigroup (Data.Grid.Internal.Grid.Grid dims a)
+ Data.Grid.Internal.Grid: instance (Data.Grid.Internal.Pretty.PrettyList (Data.Grid.Internal.NestedLists.NestedLists dims a), Data.Grid.Internal.Grid.IsGrid dims, GHC.Show.Show (Data.Grid.Internal.NestedLists.NestedLists dims a)) => GHC.Show.Show (Data.Grid.Internal.Grid.Grid dims a)
+ Data.Grid.Internal.Grid: instance (GHC.Num.Num n, Data.Grid.Internal.Grid.IsGrid dims) => GHC.Num.Num (Data.Grid.Internal.Grid.Grid dims n)
+ Data.Grid.Internal.Grid: instance (GHC.TypeNats.KnownNat n, Data.Grid.Internal.Grid.Neighboring ns) => Data.Grid.Internal.Grid.Neighboring (n : ns)
+ Data.Grid.Internal.Grid: instance Data.Grid.Internal.Grid.IsGrid '[n] => Data.Grid.Internal.Grid.Neighboring '[n]
+ Data.Grid.Internal.Grid: instance Data.Grid.Internal.Grid.IsGrid dims => Data.Distributive.Distributive (Data.Grid.Internal.Grid.Grid dims)
+ Data.Grid.Internal.Grid: instance Data.Grid.Internal.Grid.IsGrid dims => Data.Functor.Rep.Representable (Data.Grid.Internal.Grid.Grid dims)
+ Data.Grid.Internal.Grid: instance Data.Grid.Internal.Grid.IsGrid dims => GHC.Base.Applicative (Data.Grid.Internal.Grid.Grid dims)
+ Data.Grid.Internal.Grid: joinGrid :: Grid dims (Grid ns a) -> Grid (dims ++ ns) a
+ Data.Grid.Internal.Grid: neighborCoords :: Neighboring dims => Grid dims (Coord dims)
+ Data.Grid.Internal.Grid: splitGrid :: forall outer inner a from. (IsGrid from, IsGrid inner, IsGrid outer, NestedLists from a ~ NestedLists outer (NestedLists inner a)) => Grid from a -> Grid outer (Grid inner a)
+ Data.Grid.Internal.Grid: type IsGrid dims = (AllC KnownNat dims, SingI dims, Sizable dims, Representable (Grid dims), Enum (Coord dims), Bounded (Coord dims), Neighboring dims)
+ Data.Grid.Internal.NestedLists: class Sizable (dims :: [Nat])
+ Data.Grid.Internal.NestedLists: gridSize :: Sizable dims => Proxy dims -> Int
+ Data.Grid.Internal.NestedLists: instance (GHC.TypeNats.KnownNat x, Data.Grid.Internal.NestedLists.Sizable (y : xs)) => Data.Grid.Internal.NestedLists.Sizable (x : y : xs)
+ Data.Grid.Internal.NestedLists: instance GHC.TypeNats.KnownNat x => Data.Grid.Internal.NestedLists.Sizable '[x]
- Data.Grid: (//) :: forall dims a. Enum (Coord dims) => Grid dims a -> [(Coord dims, a)] -> Grid dims a
+ Data.Grid: (//) :: forall dims a. IsGrid dims => Grid dims a -> [(Coord dims, a)] -> Grid dims a
- Data.Grid: autoConvolute :: forall window dims f a b. (Dimensions dims, Dimensions window, Functor f, Neighboring window) => (Grid window (Coord dims) -> f (Coord dims)) -> (f a -> b) -> Grid dims a -> Grid dims b
+ Data.Grid: autoConvolute :: forall window dims f a b. (IsGrid dims, IsGrid window, Functor f) => (Grid window (Coord dims) -> f (Coord dims)) -> (f a -> b) -> Grid dims a -> Grid dims b
- Data.Grid: cell :: forall dims a. Dimensions dims => Coord dims -> Lens' (Grid dims a) a
+ Data.Grid: cell :: forall dims a. IsGrid dims => Coord dims -> Lens' (Grid dims a) a
- Data.Grid: clampBounds :: (Dimensions dims, Functor f) => f (Coord dims) -> f (Coord dims)
+ Data.Grid: clampBounds :: (IsGrid dims, Functor f) => f (Coord dims) -> f (Coord dims)
- Data.Grid: convolute :: forall dims f a b. (Functor f, Dimensions dims) => (Coord dims -> f (Coord dims)) -> (f a -> b) -> Grid dims a -> Grid dims b
+ Data.Grid: convolute :: forall dims f a b. (Functor f, IsGrid dims) => (Coord dims -> f (Coord dims)) -> (f a -> b) -> Grid dims a -> Grid dims b
- Data.Grid: fromList :: forall dims a. SingI dims => [a] -> Maybe (Grid dims a)
+ Data.Grid: fromList :: forall dims a. IsGrid dims => [a] -> Maybe (Grid dims a)
- Data.Grid: fromList' :: forall dims a. SingI dims => [a] -> Grid dims a
+ Data.Grid: fromList' :: forall dims a. IsGrid dims => [a] -> Grid dims a
- Data.Grid: fromNestedLists :: forall dims a. Dimensions dims => NestedLists dims a -> Maybe (Grid dims a)
+ Data.Grid: fromNestedLists :: forall dims a. IsGrid dims => NestedLists dims a -> Maybe (Grid dims a)
- Data.Grid: fromNestedLists' :: forall dims a. Dimensions dims => NestedLists dims a -> Grid dims a
+ Data.Grid: fromNestedLists' :: forall dims a. IsGrid dims => NestedLists dims a -> Grid dims a
- Data.Grid: generate :: forall dims a. SingI dims => (Int -> a) -> Grid dims a
+ Data.Grid: generate :: forall dims a. IsGrid dims => (Int -> a) -> Grid dims a
- Data.Grid: gridSize :: forall (dims :: [Nat]). SingI dims => Int
+ Data.Grid: gridSize :: Sizable dims => Proxy dims -> Int
- Data.Grid: omitBounds :: (Dimensions dims, Functor f) => f (Coord dims) -> Compose f Maybe (Coord dims)
+ Data.Grid: omitBounds :: (IsGrid dims, Functor f) => f (Coord dims) -> Compose f Maybe (Coord dims)
- Data.Grid: partitionFocus :: forall window a. (Centered window, Dimensions window) => Grid window a -> (a, Grid window (Maybe a))
+ Data.Grid: partitionFocus :: forall window a. (Centered window, IsGrid window) => Grid window a -> (a, Grid window (Maybe a))
- Data.Grid: permute :: forall (key :: [Nat]) from a invertedKey. (SingI invertedKey, invertedKey ~ InvertKey (EnumFromTo 0 (Length from - 1)) key, ValidPermutation key from, Dimensions from, Dimensions (Permuted key from)) => Grid from a -> Grid (Permuted key from) a
+ Data.Grid: permute :: forall (key :: [Nat]) from a invertedKey. (SingI invertedKey, invertedKey ~ InvertKey (EnumFromTo 0 (Length from - 1)) key, ValidPermutation key from, IsGrid from, IsGrid (Permuted key from)) => Grid from a -> Grid (Permuted key from) a
- Data.Grid: splitGrid :: forall outer inner a from. (from ~ (outer ++ inner), Dimensions from, Dimensions inner, Dimensions outer, NestedLists from a ~ NestedLists outer (NestedLists inner a)) => Grid from a -> Grid outer (Grid inner a)
+ Data.Grid: splitGrid :: forall outer inner a from. (IsGrid from, IsGrid inner, IsGrid outer, NestedLists from a ~ NestedLists outer (NestedLists inner a)) => Grid from a -> Grid outer (Grid inner a)
- Data.Grid: toNestedLists :: forall dims a. Dimensions dims => Grid dims a -> NestedLists dims a
+ Data.Grid: toNestedLists :: forall dims a. IsGrid dims => Grid dims a -> NestedLists dims a
- Data.Grid: transpose :: (KnownNat x, KnownNat y) => Grid '[x, y] a -> Grid '[y, x] a
+ Data.Grid: transpose :: (IsGrid '[x, y], IsGrid '[y, x]) => Grid '[x, y] a -> Grid '[y, x] a
- Data.Grid: window :: forall window dims. (Neighboring window, Dimensions window) => Coord dims -> Grid window (Coord dims)
+ Data.Grid: window :: forall window dims. IsGrid window => Coord dims -> Grid window (Coord dims)
- Data.Grid: wrapBounds :: (Dimensions dims, Functor f) => f (Coord dims) -> f (Coord dims)
+ Data.Grid: wrapBounds :: (IsGrid dims, Functor f) => f (Coord dims) -> f (Coord dims)
- Data.Grid.Examples.Conway: showGrid :: Dimensions '[x, y] => Grid '[x, y] Bool -> String
+ Data.Grid.Examples.Conway: showGrid :: IsGrid '[x, y] => Grid '[x, y] Bool -> String
- Data.Grid.Examples.Conway: step :: Dimensions dims => Grid dims Bool -> Grid dims Bool
+ Data.Grid.Examples.Conway: step :: IsGrid dims => Grid dims Bool -> Grid dims Bool
- Data.Grid.Examples.Intro: clampGauss :: Dimensions dims => Grid dims Double -> Grid dims Double
+ Data.Grid.Examples.Intro: clampGauss :: IsGrid dims => Grid dims Double -> Grid dims Double
- Data.Grid.Examples.Intro: gauss :: Dimensions dims => Grid dims Double -> Grid dims Double
+ Data.Grid.Examples.Intro: gauss :: IsGrid dims => Grid dims Double -> Grid dims Double
- Data.Grid.Examples.Intro: pacmanGauss :: Dimensions dims => Grid dims Double -> Grid dims Double
+ Data.Grid.Examples.Intro: pacmanGauss :: IsGrid dims => Grid dims Double -> Grid dims Double
- Data.Grid.Internal.Convolution: autoConvolute :: forall window dims f a b. (Dimensions dims, Dimensions window, Functor f, Neighboring window) => (Grid window (Coord dims) -> f (Coord dims)) -> (f a -> b) -> Grid dims a -> Grid dims b
+ Data.Grid.Internal.Convolution: autoConvolute :: forall window dims f a b. (IsGrid dims, IsGrid window, Functor f) => (Grid window (Coord dims) -> f (Coord dims)) -> (f a -> b) -> Grid dims a -> Grid dims b
- Data.Grid.Internal.Convolution: clampBounds :: (Dimensions dims, Functor f) => f (Coord dims) -> f (Coord dims)
+ Data.Grid.Internal.Convolution: clampBounds :: (IsGrid dims, Functor f) => f (Coord dims) -> f (Coord dims)
- Data.Grid.Internal.Convolution: convolute :: forall dims f a b. (Functor f, Dimensions dims) => (Coord dims -> f (Coord dims)) -> (f a -> b) -> Grid dims a -> Grid dims b
+ Data.Grid.Internal.Convolution: convolute :: forall dims f a b. (Functor f, IsGrid dims) => (Coord dims -> f (Coord dims)) -> (f a -> b) -> Grid dims a -> Grid dims b
- Data.Grid.Internal.Convolution: omitBounds :: (Dimensions dims, Functor f) => f (Coord dims) -> Compose f Maybe (Coord dims)
+ Data.Grid.Internal.Convolution: omitBounds :: (IsGrid dims, Functor f) => f (Coord dims) -> Compose f Maybe (Coord dims)
- Data.Grid.Internal.Convolution: window :: forall window dims. (Neighboring window, Dimensions window) => Coord dims -> Grid window (Coord dims)
+ Data.Grid.Internal.Convolution: window :: forall window dims. IsGrid window => Coord dims -> Grid window (Coord dims)
- Data.Grid.Internal.Convolution: wrapBounds :: (Dimensions dims, Functor f) => f (Coord dims) -> f (Coord dims)
+ Data.Grid.Internal.Convolution: wrapBounds :: (IsGrid dims, Functor f) => f (Coord dims) -> f (Coord dims)
- Data.Grid.Internal.Grid: (//) :: forall dims a. Enum (Coord dims) => Grid dims a -> [(Coord dims, a)] -> Grid dims a
+ Data.Grid.Internal.Grid: (//) :: forall dims a. IsGrid dims => Grid dims a -> [(Coord dims, a)] -> Grid dims a
- Data.Grid.Internal.Grid: fromList :: forall dims a. SingI dims => [a] -> Maybe (Grid dims a)
+ Data.Grid.Internal.Grid: fromList :: forall dims a. IsGrid dims => [a] -> Maybe (Grid dims a)
- Data.Grid.Internal.Grid: fromList' :: forall dims a. SingI dims => [a] -> Grid dims a
+ Data.Grid.Internal.Grid: fromList' :: forall dims a. IsGrid dims => [a] -> Grid dims a
- Data.Grid.Internal.Grid: fromNestedLists :: forall dims a. Dimensions dims => NestedLists dims a -> Maybe (Grid dims a)
+ Data.Grid.Internal.Grid: fromNestedLists :: forall dims a. IsGrid dims => NestedLists dims a -> Maybe (Grid dims a)
- Data.Grid.Internal.Grid: fromNestedLists' :: forall dims a. Dimensions dims => NestedLists dims a -> Grid dims a
+ Data.Grid.Internal.Grid: fromNestedLists' :: forall dims a. IsGrid dims => NestedLists dims a -> Grid dims a
- Data.Grid.Internal.Grid: generate :: forall dims a. SingI dims => (Int -> a) -> Grid dims a
+ Data.Grid.Internal.Grid: generate :: forall dims a. IsGrid dims => (Int -> a) -> Grid dims a
- Data.Grid.Internal.Grid: toNestedLists :: forall dims a. Dimensions dims => Grid dims a -> NestedLists dims a
+ Data.Grid.Internal.Grid: toNestedLists :: forall dims a. IsGrid dims => Grid dims a -> NestedLists dims a
- Data.Grid.Internal.Lens: cell :: forall dims a. Dimensions dims => Coord dims -> Lens' (Grid dims a) a
+ Data.Grid.Internal.Lens: cell :: forall dims a. IsGrid dims => Coord dims -> Lens' (Grid dims a) a
- Data.Grid.Internal.NestedLists: nestLists :: Dimensions dims => Proxy dims -> Vector a -> NestedLists dims a
+ Data.Grid.Internal.NestedLists: nestLists :: Sizable dims => Proxy dims -> Vector a -> NestedLists dims a
- Data.Grid.Internal.NestedLists: unNestLists :: Dimensions dims => Proxy dims -> NestedLists dims a -> [a]
+ Data.Grid.Internal.NestedLists: unNestLists :: Sizable dims => Proxy dims -> NestedLists dims a -> [a]
- Data.Grid.Internal.Shapes: partitionFocus :: forall window a. (Centered window, Dimensions window) => Grid window a -> (a, Grid window (Maybe a))
+ Data.Grid.Internal.Shapes: partitionFocus :: forall window a. (Centered window, IsGrid window) => Grid window a -> (a, Grid window (Maybe a))
- Data.Grid.Internal.Transpose: permute :: forall (key :: [Nat]) from a invertedKey. (SingI invertedKey, invertedKey ~ InvertKey (EnumFromTo 0 (Length from - 1)) key, ValidPermutation key from, Dimensions from, Dimensions (Permuted key from)) => Grid from a -> Grid (Permuted key from) a
+ Data.Grid.Internal.Transpose: permute :: forall (key :: [Nat]) from a invertedKey. (SingI invertedKey, invertedKey ~ InvertKey (EnumFromTo 0 (Length from - 1)) key, ValidPermutation key from, IsGrid from, IsGrid (Permuted key from)) => Grid from a -> Grid (Permuted key from) a
- Data.Grid.Internal.Transpose: transpose :: (KnownNat x, KnownNat y) => Grid '[x, y] a -> Grid '[y, x] a
+ Data.Grid.Internal.Transpose: transpose :: (IsGrid '[x, y], IsGrid '[y, x]) => Grid '[x, y] a -> Grid '[y, x] a
Files
- grids.cabal +2/−5
- src/Data/Grid.hs +6/−6
- src/Data/Grid/Examples/Conway.hs +4/−7
- src/Data/Grid/Examples/Intro.hs +3/−3
- src/Data/Grid/Internal/Convolution.hs +9/−29
- src/Data/Grid/Internal/Coord.hs +5/−10
- src/Data/Grid/Internal/Grid.hs +90/−21
- src/Data/Grid/Internal/Lens.hs +1/−1
- src/Data/Grid/Internal/Nest.hs +0/−33
- src/Data/Grid/Internal/NestedLists.hs +13/−12
- src/Data/Grid/Internal/Shapes.hs +1/−1
- src/Data/Grid/Internal/Transpose.hs +3/−3
- test/Spec/Shapes.hs +0/−8
grids.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 81ed5c93ce5bb167a555fdde42ef9944161ed9cff400c4000736623698c2582f+-- hash: f761cc1b657f2445a77f2c2026a8f1b6bfae660f46caafca8ac668576cff708a name: grids-version: 0.4.0.0+version: 0.5.0.0 description: Arbitrary sized type-safe grids with useful combinators category: Data Structures homepage: https://github.com/ChrisPenner/grids#readme@@ -50,7 +50,6 @@ build-depends: adjunctions , base >=4.7 && <5- , bifunctors , comonad , deepseq , distributive@@ -72,7 +71,6 @@ build-depends: adjunctions , base >=4.7 && <5- , bifunctors , comonad , deepseq , distributive@@ -94,7 +92,6 @@ build-depends: adjunctions , base >=4.7 && <5- , bifunctors , comonad , deepseq , distributive
src/Data/Grid.hs view
@@ -1,5 +1,7 @@ module Data.Grid- ( Grid(..)+ (+ -- * Grids+ Grid(..) -- * Creation , generate , Rep.tabulate@@ -39,22 +41,20 @@ -- * Joining , joinGrid , splitGrid- -- * Assorted- , gridSize -- * Typeclasses & Type Families- , Dimensions+ , IsGrid+ , Sizable(..) , NestedLists , Neighboring , ValidPermutation , Permuted ) where --- * Grids import Data.Grid.Internal.Grid import Data.Grid.Internal.Shapes-import Data.Grid.Internal.Nest import Data.Grid.Internal.Lens import Data.Grid.Internal.Transpose import Data.Grid.Internal.Coord import Data.Grid.Internal.Convolution+import Data.Grid.Internal.NestedLists import Data.Functor.Rep as Rep
src/Data/Grid/Examples/Conway.hs view
@@ -10,13 +10,12 @@ import Data.Functor.Compose rule' :: Grid [3, 3] Bool -> Bool-rule' (partitionFocus -> (currentCellAlive, neighbours)) = (currentCellAlive && livingNeighbours == 2) || livingNeighbours == 3+rule' (partitionFocus -> (currentCellAlive, neighbours)) =+ (currentCellAlive && livingNeighbours == 2) || livingNeighbours == 3 where livingNeighbours = length . filter id . toList . Compose $ neighbours -step- :: (Dimensions dims)- => Grid dims Bool -> Grid dims Bool+step :: (IsGrid dims) => Grid dims Bool -> Grid dims Bool step = autoConvolute @[3, 3] wrapBounds rule' glider :: [Coord '[10, 10]]@@ -32,7 +31,5 @@ showBool True = '#' showBool False = '.' -showGrid- :: (Dimensions '[x, y])- => Grid '[x, y] Bool -> String+showGrid :: (IsGrid '[x, y]) => Grid '[x, y] Bool -> String showGrid = intercalate "\n" . toNestedLists . fmap showBool
src/Data/Grid/Examples/Intro.hs view
@@ -37,13 +37,13 @@ big :: Grid '[5, 5, 5, 5] Int big = generate id -gauss :: (Dimensions dims) => Grid dims Double -> Grid dims Double+gauss :: (IsGrid dims) => Grid dims Double -> Grid dims Double gauss = autoConvolute omitBounds gauss' where gauss' :: Compose (Grid '[3, 3]) Maybe Double -> Double gauss' g = (sum g) / fromIntegral (length g) -clampGauss :: (Dimensions dims) => Grid dims Double -> Grid dims Double+clampGauss :: (IsGrid dims) => Grid dims Double -> Grid dims Double clampGauss = autoConvolute clampBounds gauss' where gauss' :: Grid '[3, 3] Double -> Double@@ -65,6 +65,6 @@ simpleGauss :: Grid '[3, 3] Double simpleGauss = gauss doubleGrid -pacmanGauss :: (Dimensions dims) => Grid dims Double -> Grid dims Double+pacmanGauss :: (IsGrid dims) => Grid dims Double -> Grid dims Double pacmanGauss = autoConvolute @'[3, 3] wrapBounds gauss' where gauss' g = sum g / fromIntegral (length g)
src/Data/Grid/Internal/Convolution.hs view
@@ -26,8 +26,6 @@ import Data.Functor.Rep import Data.Grid.Internal.Coord import Data.Grid.Internal.Grid-import Data.Grid.Internal.Nest-import GHC.TypeNats criticalError :: a criticalError = error@@ -53,17 +51,16 @@ -- repeating values at the edge of the grid when indexes are out of bounds -- (using 'clampWindow') ----- > gaussian :: (Dimensions dims) => Grid dims Double -> Grid dims Double+-- > gaussian :: (IsGrid dims) => Grid dims Double -> Grid dims Double -- > gaussian = autoConvolute clampBounds avg -- > where -- > avg :: Grid '[3, 3] Double -> Double -- > avg g = sum g / fromIntegral (length g) autoConvolute :: forall window dims f a b- . ( Dimensions dims- , Dimensions window+ . ( IsGrid dims+ , IsGrid window , Functor f- , Neighboring window ) => (Grid window (Coord dims) -> f (Coord dims)) -- ^ Restrict out of bounds coordinates in some way. Use 'clampWindow', 'wrapWindow' or 'safeWindow' -> (f a -> b) -- ^ Collapse the context down to a value@@ -76,7 +73,7 @@ -- coord, then provides a collapsing function over the same functor. convolute :: forall dims f a b- . (Functor f, Dimensions dims)+ . (Functor f, IsGrid dims) => (Coord dims -> f (Coord dims)) -- ^ Build a neighboring context within a functor from the current coord -> (f a -> b) -- ^ Collapse the context to a single value -> Grid dims a -- ^ Starting grid@@ -95,7 +92,7 @@ -- coordinates surrounding the given coord. Mostly used internally window :: forall window dims- . (Neighboring window, Dimensions window)+ . (IsGrid window) => Coord dims -> Grid window (Coord dims) window = fromWindow . neighboring . toWindow@@ -105,40 +102,23 @@ fromWindow :: Grid window (Coord window) -> Grid window (Coord dims) fromWindow = fmap coerceCoordDims -class Neighboring dims where- neighborCoords :: Grid dims (Coord dims) -instance {-# OVERLAPPING #-} (KnownNat n) => Neighboring '[n] where- neighborCoords = fromList' . fmap (Coord . pure . subtract (numVals `div` 2)) . take numVals $ [0 .. ]- where- numVals = gridSize @'[n]--instance (KnownNat n, Neighboring ns) => Neighboring (n:ns) where- neighborCoords = joinGrid (addCoord <$> currentLevelNeighbors)- where- addCoord :: Coord '[n] -> Grid ns (Coord (n : ns) )- addCoord c = appendC c <$> nestedNeighbors- nestedNeighbors :: Grid ns (Coord ns )- nestedNeighbors = neighborCoords- currentLevelNeighbors :: Grid '[n] (Coord '[n] )- currentLevelNeighbors = neighborCoords--neighboring :: (Dimensions dims, Neighboring dims) => Coord dims -> Grid dims (Coord dims)+neighboring :: (IsGrid dims) => Coord dims -> Grid dims (Coord dims) neighboring c = (c +) <$> neighborCoords -- | Use with 'autoConvolute'; Clamp out-of-bounds coordinates to the nearest in-bounds coord. clampBounds- :: (Dimensions dims, Functor f) => f (Coord dims) -> f (Coord dims)+ :: (IsGrid dims, Functor f) => f (Coord dims) -> f (Coord dims) clampBounds = fmap clampCoord -- | Use with 'autoConvolute'; Wrap out-of-bounds coordinates pac-man style to the other side of the grid wrapBounds- :: (Dimensions dims, Functor f) => f (Coord dims) -> f (Coord dims)+ :: (IsGrid dims, Functor f) => f (Coord dims) -> f (Coord dims) wrapBounds = fmap wrapCoord -- | Use with 'autoConvolute'; Out of bounds coords become 'Nothing' omitBounds- :: (Dimensions dims, Functor f) => f (Coord dims) -> Compose f Maybe (Coord dims)+ :: (IsGrid dims, Functor f) => f (Coord dims) -> Compose f Maybe (Coord dims) omitBounds = Compose . fmap wrap where wrap c | coordInBounds c = Just c
src/Data/Grid/Internal/Coord.hs view
@@ -18,10 +18,11 @@ module Data.Grid.Internal.Coord where import GHC.Exts-import GHC.TypeNats hiding ( Mod )+import GHC.TypeNats hiding (Mod) import Data.Proxy import Unsafe.Coerce import Data.Singletons.Prelude+import Data.Grid.Internal.NestedLists -- | The index type for 'Grid's. newtype Coord (dims :: [Nat]) = Coord {unCoord :: [Int]}@@ -95,17 +96,11 @@ toEnum i = Coord [i] fromEnum (Coord [i]) = clamp 0 (highestIndex @n) i -instance (KnownNat x, KnownNat y, SingI rest, Bounded (Coord rest ), Enum (Coord (y:rest) )) => Enum (Coord (x:y:rest) ) where+instance (KnownNat x, KnownNat y, Sizable (y:rest), Bounded (Coord rest ), Enum (Coord (y:rest) )) => Enum (Coord (x:y:rest) ) where toEnum i | i < 0 = negate $ toEnum (abs i) toEnum i | i > fromEnum (maxBound @(Coord (x:y:rest) )) = error "Index out of bounds"- toEnum i = (i `div` (gridSize @(y:rest))) :# toEnum (i `mod` gridSize @(y:rest))- fromEnum (x :# ys) = (clamp 0 (highestIndex @x) x * gridSize @(y:rest)) + fromEnum ys---- | Get the total size of a 'Grid' of the given dimensions------ > gridSize @'[2, 2] == 4-gridSize :: forall (dims :: [Nat]) . SingI dims => Int-gridSize = product . fmap fromIntegral $ demote @dims+ toEnum i = (i `div` (gridSize $ Proxy @(y:rest))) :# toEnum (i `mod` gridSize (Proxy @(y:rest)))+ fromEnum (x :# ys) = (clamp 0 (highestIndex @x) x * gridSize (Proxy @(y:rest))) + fromEnum ys coerceCoordDims :: Coord ns -> Coord ms coerceCoordDims = unsafeCoerce
src/Data/Grid/Internal/Grid.hs view
@@ -4,7 +4,7 @@ module Data.Grid.Internal.Grid ( Grid(..)- , Dimensions(..)+ , IsGrid , Coord , NestedLists , generate@@ -14,24 +14,44 @@ , fromList , fromList' , (//)++ , Neighboring(..)++ , joinGrid+ , splitGrid ) where +import Data.Kind import Data.Grid.Internal.NestedLists import Data.Grid.Internal.Coord import Data.Grid.Internal.Pretty import Data.Distributive import Data.Functor.Rep-import qualified Data.Vector as V+import qualified Data.Vector as V import Data.Proxy-import GHC.TypeNats as N- hiding ( Mod )+import GHC.TypeNats as N hiding (Mod) import Control.Applicative import Data.Bifunctor import Data.Maybe import Data.Singletons.Prelude import Control.DeepSeq +type family AllC (c :: x -> Constraint) (ts :: [x]) :: Constraint where+ AllC c '[] = ()+ AllC c (x:xs) = (c x, AllC c xs)+++type IsGrid dims =+ ( AllC KnownNat dims+ , SingI dims+ , Sizable dims+ , Representable (Grid dims)+ , Enum (Coord dims)+ , Bounded (Coord dims)+ , Neighboring dims+ )+ -- | An grid of arbitrary dimensions. -- -- e.g. a @Grid [2, 3] Int@ might look like:@@ -43,28 +63,28 @@ Grid {toVector :: V.Vector a} deriving (Eq, Functor, Foldable, Traversable, NFData) -instance (PrettyList (NestedLists dims a), Dimensions dims, Show (NestedLists dims a)) => Show (Grid dims a) where+instance (PrettyList (NestedLists dims a), IsGrid dims, Show (NestedLists dims a)) => Show (Grid dims a) where show g = "fromNestedLists \n" ++ (unlines . fmap (" " ++ ) . lines $ prettyList (toNestedLists g)) -instance (Dimensions dims, Semigroup a) => Semigroup (Grid dims a) where+instance (IsGrid dims, Semigroup a) => Semigroup (Grid dims a) where (<>) = liftA2 (<>) -instance (Dimensions dims, Monoid a) => Monoid (Grid dims a) where+instance (IsGrid dims, Monoid a) => Monoid (Grid dims a) where mempty = pure mempty -instance (Dimensions dims) => Applicative (Grid dims) where+instance (IsGrid dims) => Applicative (Grid dims) where pure a = tabulate (const a) liftA2 f (Grid v) (Grid u) = Grid $ V.zipWith f v u -instance (Dimensions dims) => Distributive (Grid dims) where+instance (IsGrid dims) => Distributive (Grid dims) where distribute = distributeRep -instance (Dimensions dims) => Representable (Grid dims) where+instance (IsGrid dims) => Representable (Grid dims) where type Rep (Grid dims) = Coord dims index (Grid v) c = v V.! fromEnum c- tabulate f = Grid $ V.generate (fromIntegral $ gridSize @dims) (f . toEnum . fromIntegral)+ tabulate f = Grid $ V.generate (fromIntegral $ gridSize (Proxy @dims)) (f . toEnum . fromIntegral) -instance (Num n, Dimensions dims) => Num (Grid dims n) where+instance (Num n, IsGrid dims) => Num (Grid dims n) where (+) = liftA2 (+) (*) = liftA2 (*) abs = fmap abs@@ -73,8 +93,8 @@ negate = fmap negate -- | Build a grid by selecting an element for each element-generate :: forall dims a . (SingI dims) => (Int -> a) -> Grid dims a-generate f = Grid $ V.generate (gridSize @dims) f+generate :: forall dims a . (IsGrid dims) => (Int -> a) -> Grid dims a+generate f = Grid $ V.generate (gridSize $ Proxy @dims) f -- | Turn a grid into a nested list structure. List nesting increases for each -- dimension@@ -82,7 +102,7 @@ -- > toNestedLists (G.generate id :: Grid [2, 3] Int) -- > [[0,1,2],[3,4,5]] toNestedLists- :: forall dims a . (Dimensions dims) => Grid dims a -> NestedLists dims a+ :: forall dims a . (IsGrid dims) => Grid dims a -> NestedLists dims a toNestedLists (Grid v) = nestLists (Proxy @dims) v -- | Turn a nested list structure into a Grid if the list is well formed. @@ -94,14 +114,14 @@ -- > Nothing fromNestedLists :: forall dims a- . Dimensions dims+ . IsGrid dims => NestedLists dims a -> Maybe (Grid dims a) fromNestedLists = fromList . unNestLists (Proxy @dims) -- | Partial variant of 'fromNestedLists' which errors on malformed input fromNestedLists'- :: forall dims a . Dimensions dims => NestedLists dims a -> Grid dims a+ :: forall dims a . IsGrid dims => NestedLists dims a -> Grid dims a fromNestedLists' = fromJust . fromNestedLists -- | Convert a list into a Grid or fail if not provided the correct number of@@ -111,20 +131,69 @@ -- > Just (Grid [[0,1,2],[3,4,5]]) -- > G.fromList [0, 1, 2, 3] :: Maybe (Grid [2, 3] Int) -- > Nothing-fromList :: forall dims a . (SingI dims) => [a] -> Maybe (Grid dims a)+fromList :: forall dims a . (IsGrid dims) => [a] -> Maybe (Grid dims a) fromList xs = let v = V.fromList xs- in if V.length v == gridSize @dims then Just $ Grid v else Nothing+ in if V.length v == gridSize (Proxy @dims) then Just $ Grid v else Nothing -- | Partial variant of 'fromList' which errors on malformed input-fromList' :: forall dims a . (SingI dims) => [a] -> Grid dims a+fromList' :: forall dims a . (IsGrid dims) => [a] -> Grid dims a fromList' = fromJust . fromList -- | Update elements of a grid (//) :: forall dims a- . (Enum (Coord dims ))+ . IsGrid dims => Grid dims a -> [(Coord dims , a)] -> Grid dims a (Grid v) // xs = Grid (v V.// fmap (first fromEnum) xs)++class Neighboring dims where+ neighborCoords :: Grid dims (Coord dims)+++instance {-# OVERLAPPING #-} (IsGrid '[n]) => Neighboring '[n] where+ neighborCoords = fromList' . fmap (Coord . pure . subtract (numVals `div` 2)) . take numVals $ [0 .. ]+ where+ numVals = gridSize (Proxy @'[n])++instance (KnownNat n, Neighboring ns) => Neighboring (n:ns) where+ neighborCoords = joinGrid (addCoord <$> currentLevelNeighbors)+ where+ addCoord :: Coord '[n] -> Grid ns (Coord (n : ns) )+ addCoord c = appendC c <$> nestedNeighbors+ nestedNeighbors :: Grid ns (Coord ns )+ nestedNeighbors = neighborCoords+ currentLevelNeighbors :: Grid '[n] (Coord '[n] )+ currentLevelNeighbors = neighborCoords+++-- | The inverse of 'splitGrid', +-- joinGrid will nest a grid from:+-- > Grid outer (Grid inner a) -> Grid (outer ++ inner) a+--+-- For example, you can nest a simple 3x3 from smaller [3] grids as follows:+--+-- > joinGrid (myGrid :: Grid [3] (Grid [3] a)) :: Grid '[3, 3] a+joinGrid :: Grid dims (Grid ns a) -> Grid (dims ++ ns) a+joinGrid (Grid v) = Grid (v >>= toVector)++-- | The inverse of 'joinGrid', +-- splitGrid @outerDims @innerDims will un-nest a grid from:+-- > Grid (outer ++ inner) a -> Grid outer (Grid inner a)+--+-- For example, you can unnest a simple 3x3 as follows:+--+-- > splitGrid @'[3] @'[3] myGrid :: Grid '[3] (Grid [3] a)+splitGrid :: forall outer inner a from.+ ( IsGrid from+ , IsGrid inner+ , IsGrid outer+ , NestedLists from a ~ NestedLists outer (NestedLists inner a)+ )+ => Grid from a+ -> Grid outer (Grid inner a)+splitGrid = fmap fromNestedLists' . fromNestedLists' . toNestedLists++
src/Data/Grid/Internal/Lens.hs view
@@ -16,7 +16,7 @@ -- | Focus an element of a 'Grid' given its 'Coord' cell :: forall dims a- . (Dimensions dims)+ . (IsGrid dims) => Coord dims -> Lens' (Grid dims a) a cell c = lens get set
src/Data/Grid/Internal/Nest.hs view
@@ -3,36 +3,3 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# OPTIONS_GHC -fno-warn-redundant-constraints #-} module Data.Grid.Internal.Nest where--import Data.Grid.Internal.Grid-import Data.Singletons.Prelude----- | The inverse of 'splitGrid', --- joinGrid will nest a grid from:--- > Grid outer (Grid inner a) -> Grid (outer ++ inner) a------ For example, you can nest a simple 3x3 from smaller [3] grids as follows:------ > joinGrid (myGrid :: Grid [3] (Grid [3] a)) :: Grid '[3, 3] a-joinGrid :: Grid dims (Grid ns a) -> Grid (dims ++ ns) a-joinGrid (Grid v) = Grid (v >>= toVector)---- | The inverse of 'joinGrid', --- splitGrid @outerDims @innerDims will un-nest a grid from:--- > Grid (outer ++ inner) a -> Grid outer (Grid inner a)------ For example, you can unnest a simple 3x3 as follows:------ > splitGrid @'[3] @'[3] myGrid :: Grid '[3] (Grid [3] a)-splitGrid- :: forall outer inner a from- . ( from ~ (outer ++ inner)- , Dimensions from- , Dimensions inner- , Dimensions outer- , NestedLists from a ~ NestedLists outer (NestedLists inner a)- )- => Grid from a- -> Grid outer (Grid inner a)-splitGrid = fmap fromNestedLists' . fromNestedLists' . toNestedLists
src/Data/Grid/Internal/NestedLists.hs view
@@ -2,15 +2,9 @@ {-# LANGUAGE UndecidableSuperClasses #-} module Data.Grid.Internal.NestedLists where -import Data.Kind-import GHC.TypeNats as N+import GHC.TypeNats as N import Data.Singletons.Prelude-import qualified Data.Vector as V-import Data.Grid.Internal.Coord--type family AllC (c :: x -> Constraint) (ts :: [x]) :: Constraint where- AllC c '[] = ()- AllC c (x:xs) = (c x, AllC c xs)+import qualified Data.Vector as V -- | Computes the level of nesting requried to represent a given grid -- dimensionality as a nested list@@ -31,14 +25,21 @@ -- | Represents valid dimensionalities. All non empty lists of Nats have -- an instance-class (AllC KnownNat dims, SingI dims, Enum (Coord dims), Bounded (Coord dims)) => Dimensions (dims :: [Nat]) where+class Sizable (dims :: [Nat]) where nestLists :: Proxy dims -> V.Vector a -> NestedLists dims a unNestLists :: Proxy dims -> NestedLists dims a -> [a] -instance (KnownNat x) => Dimensions '[x] where+ -- | Get the total size of a 'Grid' of the given dimensions+ --+ -- > gridSize (Proxy @'[2, 2]) == 4+ gridSize :: Proxy dims -> Int++instance {-# OVERLAPPING #-} KnownNat x => Sizable '[x] where nestLists _ = V.toList unNestLists _ xs = xs+ gridSize _ = fromIntegral $ natVal (Proxy @x) -instance (KnownNat x, Bounded (Coord xs), SingI xs, Dimensions (y:xs)) => Dimensions (x:y:xs) where- nestLists _ v = nestLists (Proxy @(y:xs)) <$> chunkVector (gridSize @(y:xs)) v+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))
src/Data/Grid/Internal/Shapes.hs view
@@ -22,7 +22,7 @@ import Data.Grid.Internal.Errors partitionFocus :: forall window a.- (Centered window, Dimensions window)+ (Centered window, IsGrid window) => Grid window a -> (a, Grid window (Maybe a)) partitionFocus g = (g `index` centerCoord @window, imapRep wrapMaybe g)
src/Data/Grid/Internal/Transpose.hs view
@@ -57,8 +57,8 @@ . ( SingI invertedKey , invertedKey ~ InvertKey (EnumFromTo 0 (Length from TL.- 1)) key , ValidPermutation key from- , Dimensions from - , Dimensions (Permuted key from) + , IsGrid from + , IsGrid (Permuted key from) ) => Grid from a -> Grid (Permuted key from) a@@ -85,7 +85,7 @@ -- | Transpose a 2 dimensional matrix. Equivalent to: -- -- > permute @[1, 0]-transpose :: (KnownNat x, KnownNat y) => Grid '[x, y] a -> Grid '[y, x] a+transpose :: (IsGrid '[x, y], IsGrid '[y, x]) => Grid '[x, y] a -> Grid '[y, x] a transpose = permute @'[1, 0] -- | Get the inverse of a permutation pattern, used internally
test/Spec/Shapes.hs view
@@ -3,20 +3,12 @@ module Spec.Shapes (spec) where import Test.Hspec hiding (focus)-import qualified Data.Vector as V import Data.Grid as G-import Control.Applicative-import Data.Maybe import Data.Functor.Compose-import Control.Comonad import Control.Monad-import Data.Coerce smallGrid :: Grid '[2, 2] Int smallGrid = generate id--medGrid :: Grid '[3, 3] Int-medGrid = generate id spec :: Spec spec =