Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
- newtype Grid (dims :: [Nat]) a = Grid {}
- generate :: forall dims a. SingI dims => (Int -> a) -> Grid dims a
- tabulate :: Representable f => (Rep f -> a) -> f a
- fromNestedLists :: forall dims a. Dimensions dims => NestedLists dims a -> Maybe (Grid dims a)
- fromNestedLists' :: forall dims a. Dimensions dims => NestedLists dims a -> Grid dims a
- fromList :: forall dims a. SingI dims => [a] -> Maybe (Grid dims a)
- fromList' :: forall dims a. SingI dims => [a] -> Grid dims a
- toNestedLists :: forall dims a. Dimensions dims => Grid dims a -> NestedLists dims a
- newtype Coord (dims :: [Nat]) = Coord {}
- coord :: forall dims. SingI dims => [Int] -> Maybe (Coord dims)
- unconsC :: Coord (n ': ns) -> (Int, Coord ns)
- appendC :: Coord ns -> Coord ms -> Coord (ns ++ ms)
- index :: Representable f => f a -> Rep f -> a
- (//) :: forall dims a. Enum (Coord dims) => Grid dims a -> [(Coord dims, a)] -> Grid dims a
- cell :: forall dims a. Dimensions dims => Coord dims -> Lens' (Grid dims a) a
- 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
- convolute :: forall dims f a b. (Functor f, Dimensions dims) => (Coord dims -> f (Coord dims)) -> (f a -> b) -> Grid dims a -> Grid dims b
- window :: forall window dims. (Neighboring window, Dimensions window) => Coord dims -> Grid window (Coord dims)
- partitionFocus :: forall window a. (Centered window, Dimensions window) => Grid window a -> (a, Grid window (Maybe a))
- centerCoord :: Centered dims => Coord dims
- clampBounds :: (Dimensions dims, Functor f) => f (Coord dims) -> f (Coord dims)
- wrapBounds :: (Dimensions dims, Functor f) => f (Coord dims) -> f (Coord dims)
- omitBounds :: (Dimensions dims, Functor f) => f (Coord dims) -> Compose f Maybe (Coord dims)
- transpose :: (KnownNat x, KnownNat y) => Grid '[x, y] a -> Grid '[y, x] a
- 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
- permuteCoord :: forall (key :: [Nat]) to from. SingI key => Coord from -> Coord to
- joinGrid :: Grid dims (Grid ns a) -> Grid (dims ++ ns) 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)
- gridSize :: forall (dims :: [Nat]). SingI dims => Int
- class (AllC KnownNat dims, SingI dims, Enum (Coord dims), Bounded (Coord dims)) => Dimensions (dims :: [Nat])
- type family NestedLists (dims :: [Nat]) a where ...
- class Neighboring dims
- type ValidPermutation key from = (Sort key == EnumFromTo 0 (Length from - 1)) ?! (((((Text "Malformed permutation hint: " :<>: ShowType key) :$$: (Text "When permuting matrix of size: " :<>: ShowType from)) :$$: (Text "Key must be a permutation of " :<>: ShowType (EnumFromTo 0 (Length from - 1)))) :$$: Text "e.g. the identity permutation for 2x2 is @[0, 1]") :$$: Text "e.g. matrix transpose for 2x2 is @[1, 0]")
- type family Permuted (key :: [Nat]) (from :: [Nat]) :: [Nat] where ...
Grids
newtype Grid (dims :: [Nat]) a Source #
An grid of arbitrary dimensions.
e.g. a Grid [2, 3] Int
might look like:
generate id :: Grid [2, 3] Int fromNestedLists [[0,1,2], [3,4,5]]
Instances
Functor (Grid dims) Source # | |
Dimensions dims => Applicative (Grid dims) Source # | |
Foldable (Grid dims) Source # | |
Defined in Data.Grid.Internal.Grid fold :: Monoid m => Grid dims m -> m # foldMap :: Monoid m => (a -> m) -> Grid dims a -> m # foldr :: (a -> b -> b) -> b -> Grid dims a -> b # foldr' :: (a -> b -> b) -> b -> Grid dims a -> b # foldl :: (b -> a -> b) -> b -> Grid dims a -> b # foldl' :: (b -> a -> b) -> b -> Grid dims a -> b # foldr1 :: (a -> a -> a) -> Grid dims a -> a # foldl1 :: (a -> a -> a) -> Grid dims a -> a # toList :: Grid dims a -> [a] # length :: Grid dims a -> Int # elem :: Eq a => a -> Grid dims a -> Bool # maximum :: Ord a => Grid dims a -> a # minimum :: Ord a => Grid dims a -> a # | |
Traversable (Grid dims) Source # | |
Defined in Data.Grid.Internal.Grid | |
Dimensions dims => Distributive (Grid dims) Source # | |
Dimensions dims => Representable (Grid dims) Source # | |
Eq a => Eq (Grid dims a) Source # | |
(Num n, Dimensions dims) => Num (Grid dims n) Source # | |
Defined in Data.Grid.Internal.Grid (+) :: Grid dims n -> Grid dims n -> Grid dims n # (-) :: Grid dims n -> Grid dims n -> Grid dims n # (*) :: Grid dims n -> Grid dims n -> Grid dims n # negate :: Grid dims n -> Grid dims n # abs :: Grid dims n -> Grid dims n # signum :: Grid dims n -> Grid dims n # fromInteger :: Integer -> Grid dims n # | |
(PrettyList (NestedLists dims a), Dimensions dims, Show (NestedLists dims a)) => Show (Grid dims a) Source # | |
(Dimensions dims, Semigroup a) => Semigroup (Grid dims a) Source # | |
(Dimensions dims, Monoid a) => Monoid (Grid dims a) Source # | |
NFData a => NFData (Grid dims a) Source # | |
Defined in Data.Grid.Internal.Grid | |
type Rep (Grid dims) Source # | |
Defined in Data.Grid.Internal.Grid |
Creation
generate :: forall dims a. SingI dims => (Int -> a) -> Grid dims a Source #
Build a grid by selecting an element for each element
tabulate :: Representable f => (Rep f -> a) -> f a #
fromNestedLists :: forall dims a. Dimensions dims => NestedLists dims a -> Maybe (Grid dims a) Source #
Turn a nested list structure into a Grid if the list is well formed. Required list nesting increases for each dimension
fromNestedLists [[0,1,2],[3,4,5]] :: Maybe (Grid [2, 3] Int) Just (Grid [[0,1,2],[3,4,5]]) fromNestedLists [[0],[1,2]] :: Maybe (Grid [2, 3] Int) Nothing
fromNestedLists' :: forall dims a. Dimensions dims => NestedLists dims a -> Grid dims a Source #
Partial variant of fromNestedLists
which errors on malformed input
fromList :: forall dims a. SingI dims => [a] -> Maybe (Grid dims a) Source #
Convert a list into a Grid or fail if not provided the correct number of elements
G.fromList [0, 1, 2, 3, 4, 5] :: Maybe (Grid [2, 3] Int) 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] -> Grid dims a Source #
Partial variant of fromList
which errors on malformed input
Collapsing
toNestedLists :: forall dims a. Dimensions dims => Grid dims a -> NestedLists dims a Source #
Turn a grid into a nested list structure. List nesting increases for each dimension
toNestedLists (G.generate id :: Grid [2, 3] Int) [[0,1,2],[3,4,5]]
Indexing
newtype Coord (dims :: [Nat]) Source #
The index type for Grid
s.
Instances
IsList (Coord dims) Source # | |
(KnownNat n, Bounded (Coord ns)) => Bounded (Coord (n ': ns)) Source # | |
Bounded (Coord ([] :: [Nat])) Source # | |
(KnownNat x, KnownNat y, SingI rest, Bounded (Coord rest), Enum (Coord (y ': rest))) => Enum (Coord (x ': (y ': rest))) Source # | |
Defined in Data.Grid.Internal.Coord succ :: Coord (x ': (y ': rest)) -> Coord (x ': (y ': rest)) # pred :: Coord (x ': (y ': rest)) -> Coord (x ': (y ': rest)) # toEnum :: Int -> Coord (x ': (y ': rest)) # fromEnum :: Coord (x ': (y ': rest)) -> Int # enumFrom :: Coord (x ': (y ': rest)) -> [Coord (x ': (y ': rest))] # enumFromThen :: Coord (x ': (y ': rest)) -> Coord (x ': (y ': rest)) -> [Coord (x ': (y ': rest))] # enumFromTo :: Coord (x ': (y ': rest)) -> Coord (x ': (y ': rest)) -> [Coord (x ': (y ': rest))] # enumFromThenTo :: Coord (x ': (y ': rest)) -> Coord (x ': (y ': rest)) -> Coord (x ': (y ': rest)) -> [Coord (x ': (y ': rest))] # | |
KnownNat n => Enum (Coord (n ': ([] :: [Nat]))) Source # | |
Defined in Data.Grid.Internal.Coord succ :: Coord (n ': []) -> Coord (n ': []) # pred :: Coord (n ': []) -> Coord (n ': []) # toEnum :: Int -> Coord (n ': []) # fromEnum :: Coord (n ': []) -> Int # enumFrom :: Coord (n ': []) -> [Coord (n ': [])] # enumFromThen :: Coord (n ': []) -> Coord (n ': []) -> [Coord (n ': [])] # enumFromTo :: Coord (n ': []) -> Coord (n ': []) -> [Coord (n ': [])] # enumFromThenTo :: Coord (n ': []) -> Coord (n ': []) -> Coord (n ': []) -> [Coord (n ': [])] # | |
Eq (Coord dims) Source # | |
Enum (Coord ns) => Num (Coord ns) Source # | |
Show (Coord dims) Source # | |
type Item (Coord dims) Source # | |
Defined in Data.Grid.Internal.Coord |
coord :: forall dims. SingI dims => [Int] -> Maybe (Coord dims) Source #
Safely construct a Coord
for a given grid size, checking that all
indexes are in range
λ> coord @[3, 3] [1, 2] Just [1, 2] λ> coord @[3, 3] [3, 3] Nothing λ> coord @[3, 3] [1, 2, 3] Nothing
index :: Representable f => f a -> Rep f -> a #
If no definition is provided, this will default to gindex
.
Updating
(//) :: forall dims a. Enum (Coord dims) => Grid dims a -> [(Coord dims, a)] -> Grid dims a Source #
Update elements of a grid
Lenses
Convolution
:: (Dimensions dims, Dimensions window, Functor f, Neighboring window) | |
=> (Grid window (Coord dims) -> f (Coord dims)) | Restrict out of bounds coordinates in some way. Use |
-> (f a -> b) | Collapse the context down to a value |
-> Grid dims a | Starting grid |
-> Grid dims b |
Perform a computation based on the context surrounding a cell Good for doing things like Linear Image Filters (e.g. gaussian blur) or simulating Cellular Automata (e.g. Conway's game of life)
This function accepts a function which indicates what to do with
'out-of-bounds' indexes, clampWindow
, wrapWindow
and safeWindow
are examples.
It also acccepts a transformation function which operates over the functor created by the first parameter and collapses it down to a new value for the cell at that position.
This function is best used with Type Applications to denote the desired window size; the Grid passed to the given function contains the current cell (in the middle) and all the surrounding cells.
Here's an example of computing the average of all neighboring cells,
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 = autoConvolute clampBounds avg where avg :: Grid '[3, 3] Double -> Double avg g = sum g / fromIntegral (length g)
:: (Functor f, Dimensions 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 |
-> Grid dims b |
This is a fully generic version of autoConvolute
which allows
the user to provide a function which builds a context from the current
coord, then provides a collapsing function over the same functor.
window :: forall window dims. (Neighboring window, Dimensions window) => Coord dims -> Grid window (Coord dims) Source #
Given a coordinate generate a grid of size window
filled with
coordinates surrounding the given coord. Mostly used internally
Convolution Utils
partitionFocus :: forall window a. (Centered window, Dimensions window) => Grid window a -> (a, Grid window (Maybe a)) Source #
centerCoord :: Centered dims => Coord dims Source #
Bounds restriction
clampBounds :: (Dimensions dims, Functor f) => f (Coord dims) -> f (Coord dims) Source #
Use with autoConvolute
; Clamp out-of-bounds coordinates to the nearest in-bounds coord.
wrapBounds :: (Dimensions dims, Functor f) => f (Coord dims) -> f (Coord dims) Source #
Use with autoConvolute
; Wrap out-of-bounds coordinates pac-man style to the other side of the grid
omitBounds :: (Dimensions dims, Functor f) => f (Coord dims) -> Compose f Maybe (Coord dims) Source #
Use with autoConvolute
; Out of bounds coords become Nothing
Permutations
transpose :: (KnownNat x, KnownNat y) => Grid '[x, y] a -> Grid '[y, x] a Source #
Transpose a 2 dimensional matrix. Equivalent to:
permute @[1, 0]
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 Source #
Permute dimensions of a Grid
. This is similar to MatLab's permute
function
permute
requires a type application containing a permutation pattern;
The pattern is a re-ordering of the list [0..n]
which represents the new
dimension order. For example the permutation pattern [1, 2, 0]
when
applied to the dimensions [4, 5, 6]
results in the dimensions [5, 6, 4]
.
For 2 dimensional matrixes, a permutation using [1, 0]
is simply a
matrix transpose
λ> small fromNestedLists [[0,1,2] ,[3,4,5] ,[6,7,8]] λ> permute @[1, 0] small fromNestedLists [[0,3,6] ,[1,4,7] ,[2,5,8]]
permuteCoord :: forall (key :: [Nat]) to from. SingI key => Coord from -> Coord to Source #
Permute the dimensions of a coordinate according to a permutation pattern.
see permute
regarding permutation patterns
Joining
joinGrid :: Grid dims (Grid ns a) -> Grid (dims ++ ns) a Source #
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
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) Source #
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)
Assorted
gridSize :: forall (dims :: [Nat]). SingI dims => Int Source #
Get the total size of a Grid
of the given dimensions
gridSize @'[2, 2] == 4
Typeclasses & Type Families
class (AllC KnownNat dims, SingI dims, Enum (Coord dims), Bounded (Coord dims)) => Dimensions (dims :: [Nat]) Source #
Represents valid dimensionalities. All non empty lists of Nats have an instance
Instances
(KnownNat x, Bounded (Coord xs), SingI xs, Dimensions (y ': xs)) => Dimensions (x ': (y ': xs)) Source # | |
Defined in Data.Grid.Internal.NestedLists nestLists :: Proxy (x ': (y ': xs)) -> Vector a -> NestedLists (x ': (y ': xs)) a Source # unNestLists :: Proxy (x ': (y ': xs)) -> NestedLists (x ': (y ': xs)) a -> [a] Source # | |
KnownNat x => Dimensions (x ': ([] :: [Nat])) Source # | |
Defined in Data.Grid.Internal.NestedLists nestLists :: Proxy (x ': []) -> Vector a -> NestedLists (x ': []) a Source # unNestLists :: Proxy (x ': []) -> NestedLists (x ': []) a -> [a] Source # |
type family NestedLists (dims :: [Nat]) a where ... Source #
Computes the level of nesting requried to represent a given grid dimensionality as a nested list
NestedLists [2, 3] Int == [[Int]] NestedLists [2, 3, 4] Int == [[[Int]]]
NestedLists '[] a = a | |
NestedLists (_ ': xs) a = [NestedLists xs a] |
class Neighboring dims Source #
neighborCoords
Instances
(KnownNat n, Neighboring ns) => Neighboring (n ': ns) Source # | |
Defined in Data.Grid.Internal.Convolution neighborCoords :: Grid (n ': ns) (Coord (n ': ns)) | |
KnownNat n => Neighboring (n ': ([] :: [Nat])) Source # | |
Defined in Data.Grid.Internal.Convolution neighborCoords :: Grid (n ': []) (Coord (n ': [])) |
type ValidPermutation key from = (Sort key == EnumFromTo 0 (Length from - 1)) ?! (((((Text "Malformed permutation hint: " :<>: ShowType key) :$$: (Text "When permuting matrix of size: " :<>: ShowType from)) :$$: (Text "Key must be a permutation of " :<>: ShowType (EnumFromTo 0 (Length from - 1)))) :$$: Text "e.g. the identity permutation for 2x2 is @[0, 1]") :$$: Text "e.g. matrix transpose for 2x2 is @[1, 0]") Source #