-- |
-- SPDX-License-Identifier: BSD-3-Clause
module Swarm.Game.Scenario.Topography.Grid (
  Grid (..),
  NonEmptyGrid (..),
  gridToVec,
  mapWithCoords,
  mapWithCoordsNE,
  allMembers,
  allMembersNE,
  mapRowsNE,
  getRows,
  mkGrid,
  getNonEmptyGrid,
)
where

import Control.Lens.Indexed (FunctorWithIndex, imap)
import Data.Aeson (ToJSON (..))
import Data.Foldable qualified as F
import Data.List.NonEmpty (NonEmpty)
import Data.List.NonEmpty qualified as NE
import Data.Maybe (fromMaybe)
import Data.Semigroup
import Data.Tuple.Extra (both)
import Data.Vector qualified as V
import GHC.Generics (Generic)
import Swarm.Game.World.Coords
import Prelude hiding (zipWith)

newtype NonEmptyGrid c = NonEmptyGrid (NonEmpty (NonEmpty c))
  deriving ((forall x. NonEmptyGrid c -> Rep (NonEmptyGrid c) x)
-> (forall x. Rep (NonEmptyGrid c) x -> NonEmptyGrid c)
-> Generic (NonEmptyGrid c)
forall x. Rep (NonEmptyGrid c) x -> NonEmptyGrid c
forall x. NonEmptyGrid c -> Rep (NonEmptyGrid c) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall c x. Rep (NonEmptyGrid c) x -> NonEmptyGrid c
forall c x. NonEmptyGrid c -> Rep (NonEmptyGrid c) x
$cfrom :: forall c x. NonEmptyGrid c -> Rep (NonEmptyGrid c) x
from :: forall x. NonEmptyGrid c -> Rep (NonEmptyGrid c) x
$cto :: forall c x. Rep (NonEmptyGrid c) x -> NonEmptyGrid c
to :: forall x. Rep (NonEmptyGrid c) x -> NonEmptyGrid c
Generic, Int -> NonEmptyGrid c -> ShowS
[NonEmptyGrid c] -> ShowS
NonEmptyGrid c -> String
(Int -> NonEmptyGrid c -> ShowS)
-> (NonEmptyGrid c -> String)
-> ([NonEmptyGrid c] -> ShowS)
-> Show (NonEmptyGrid c)
forall c. Show c => Int -> NonEmptyGrid c -> ShowS
forall c. Show c => [NonEmptyGrid c] -> ShowS
forall c. Show c => NonEmptyGrid c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall c. Show c => Int -> NonEmptyGrid c -> ShowS
showsPrec :: Int -> NonEmptyGrid c -> ShowS
$cshow :: forall c. Show c => NonEmptyGrid c -> String
show :: NonEmptyGrid c -> String
$cshowList :: forall c. Show c => [NonEmptyGrid c] -> ShowS
showList :: [NonEmptyGrid c] -> ShowS
Show, NonEmptyGrid c -> NonEmptyGrid c -> Bool
(NonEmptyGrid c -> NonEmptyGrid c -> Bool)
-> (NonEmptyGrid c -> NonEmptyGrid c -> Bool)
-> Eq (NonEmptyGrid c)
forall c. Eq c => NonEmptyGrid c -> NonEmptyGrid c -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall c. Eq c => NonEmptyGrid c -> NonEmptyGrid c -> Bool
== :: NonEmptyGrid c -> NonEmptyGrid c -> Bool
$c/= :: forall c. Eq c => NonEmptyGrid c -> NonEmptyGrid c -> Bool
/= :: NonEmptyGrid c -> NonEmptyGrid c -> Bool
Eq, (forall a b. (a -> b) -> NonEmptyGrid a -> NonEmptyGrid b)
-> (forall a b. a -> NonEmptyGrid b -> NonEmptyGrid a)
-> Functor NonEmptyGrid
forall a b. a -> NonEmptyGrid b -> NonEmptyGrid a
forall a b. (a -> b) -> NonEmptyGrid a -> NonEmptyGrid b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> NonEmptyGrid a -> NonEmptyGrid b
fmap :: forall a b. (a -> b) -> NonEmptyGrid a -> NonEmptyGrid b
$c<$ :: forall a b. a -> NonEmptyGrid b -> NonEmptyGrid a
<$ :: forall a b. a -> NonEmptyGrid b -> NonEmptyGrid a
Functor, (forall m. Monoid m => NonEmptyGrid m -> m)
-> (forall m a. Monoid m => (a -> m) -> NonEmptyGrid a -> m)
-> (forall m a. Monoid m => (a -> m) -> NonEmptyGrid a -> m)
-> (forall a b. (a -> b -> b) -> b -> NonEmptyGrid a -> b)
-> (forall a b. (a -> b -> b) -> b -> NonEmptyGrid a -> b)
-> (forall b a. (b -> a -> b) -> b -> NonEmptyGrid a -> b)
-> (forall b a. (b -> a -> b) -> b -> NonEmptyGrid a -> b)
-> (forall a. (a -> a -> a) -> NonEmptyGrid a -> a)
-> (forall a. (a -> a -> a) -> NonEmptyGrid a -> a)
-> (forall a. NonEmptyGrid a -> [a])
-> (forall a. NonEmptyGrid a -> Bool)
-> (forall a. NonEmptyGrid a -> Int)
-> (forall a. Eq a => a -> NonEmptyGrid a -> Bool)
-> (forall a. Ord a => NonEmptyGrid a -> a)
-> (forall a. Ord a => NonEmptyGrid a -> a)
-> (forall a. Num a => NonEmptyGrid a -> a)
-> (forall a. Num a => NonEmptyGrid a -> a)
-> Foldable NonEmptyGrid
forall a. Eq a => a -> NonEmptyGrid a -> Bool
forall a. Num a => NonEmptyGrid a -> a
forall a. Ord a => NonEmptyGrid a -> a
forall m. Monoid m => NonEmptyGrid m -> m
forall a. NonEmptyGrid a -> Bool
forall a. NonEmptyGrid a -> Int
forall a. NonEmptyGrid a -> [a]
forall a. (a -> a -> a) -> NonEmptyGrid a -> a
forall m a. Monoid m => (a -> m) -> NonEmptyGrid a -> m
forall b a. (b -> a -> b) -> b -> NonEmptyGrid a -> b
forall a b. (a -> b -> b) -> b -> NonEmptyGrid a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => NonEmptyGrid m -> m
fold :: forall m. Monoid m => NonEmptyGrid m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> NonEmptyGrid a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> NonEmptyGrid a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> NonEmptyGrid a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> NonEmptyGrid a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> NonEmptyGrid a -> b
foldr :: forall a b. (a -> b -> b) -> b -> NonEmptyGrid a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> NonEmptyGrid a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> NonEmptyGrid a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> NonEmptyGrid a -> b
foldl :: forall b a. (b -> a -> b) -> b -> NonEmptyGrid a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> NonEmptyGrid a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> NonEmptyGrid a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> NonEmptyGrid a -> a
foldr1 :: forall a. (a -> a -> a) -> NonEmptyGrid a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> NonEmptyGrid a -> a
foldl1 :: forall a. (a -> a -> a) -> NonEmptyGrid a -> a
$ctoList :: forall a. NonEmptyGrid a -> [a]
toList :: forall a. NonEmptyGrid a -> [a]
$cnull :: forall a. NonEmptyGrid a -> Bool
null :: forall a. NonEmptyGrid a -> Bool
$clength :: forall a. NonEmptyGrid a -> Int
length :: forall a. NonEmptyGrid a -> Int
$celem :: forall a. Eq a => a -> NonEmptyGrid a -> Bool
elem :: forall a. Eq a => a -> NonEmptyGrid a -> Bool
$cmaximum :: forall a. Ord a => NonEmptyGrid a -> a
maximum :: forall a. Ord a => NonEmptyGrid a -> a
$cminimum :: forall a. Ord a => NonEmptyGrid a -> a
minimum :: forall a. Ord a => NonEmptyGrid a -> a
$csum :: forall a. Num a => NonEmptyGrid a -> a
sum :: forall a. Num a => NonEmptyGrid a -> a
$cproduct :: forall a. Num a => NonEmptyGrid a -> a
product :: forall a. Num a => NonEmptyGrid a -> a
Foldable, Functor NonEmptyGrid
Foldable NonEmptyGrid
(Functor NonEmptyGrid, Foldable NonEmptyGrid) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> NonEmptyGrid a -> f (NonEmptyGrid b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    NonEmptyGrid (f a) -> f (NonEmptyGrid a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> NonEmptyGrid a -> m (NonEmptyGrid b))
-> (forall (m :: * -> *) a.
    Monad m =>
    NonEmptyGrid (m a) -> m (NonEmptyGrid a))
-> Traversable NonEmptyGrid
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
NonEmptyGrid (m a) -> m (NonEmptyGrid a)
forall (f :: * -> *) a.
Applicative f =>
NonEmptyGrid (f a) -> f (NonEmptyGrid a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> NonEmptyGrid a -> m (NonEmptyGrid b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NonEmptyGrid a -> f (NonEmptyGrid b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NonEmptyGrid a -> f (NonEmptyGrid b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NonEmptyGrid a -> f (NonEmptyGrid b)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
NonEmptyGrid (f a) -> f (NonEmptyGrid a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
NonEmptyGrid (f a) -> f (NonEmptyGrid a)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> NonEmptyGrid a -> m (NonEmptyGrid b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> NonEmptyGrid a -> m (NonEmptyGrid b)
$csequence :: forall (m :: * -> *) a.
Monad m =>
NonEmptyGrid (m a) -> m (NonEmptyGrid a)
sequence :: forall (m :: * -> *) a.
Monad m =>
NonEmptyGrid (m a) -> m (NonEmptyGrid a)
Traversable, [NonEmptyGrid c] -> Value
[NonEmptyGrid c] -> Encoding
NonEmptyGrid c -> Bool
NonEmptyGrid c -> Value
NonEmptyGrid c -> Encoding
(NonEmptyGrid c -> Value)
-> (NonEmptyGrid c -> Encoding)
-> ([NonEmptyGrid c] -> Value)
-> ([NonEmptyGrid c] -> Encoding)
-> (NonEmptyGrid c -> Bool)
-> ToJSON (NonEmptyGrid c)
forall c. ToJSON c => [NonEmptyGrid c] -> Value
forall c. ToJSON c => [NonEmptyGrid c] -> Encoding
forall c. ToJSON c => NonEmptyGrid c -> Bool
forall c. ToJSON c => NonEmptyGrid c -> Value
forall c. ToJSON c => NonEmptyGrid c -> Encoding
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: forall c. ToJSON c => NonEmptyGrid c -> Value
toJSON :: NonEmptyGrid c -> Value
$ctoEncoding :: forall c. ToJSON c => NonEmptyGrid c -> Encoding
toEncoding :: NonEmptyGrid c -> Encoding
$ctoJSONList :: forall c. ToJSON c => [NonEmptyGrid c] -> Value
toJSONList :: [NonEmptyGrid c] -> Value
$ctoEncodingList :: forall c. ToJSON c => [NonEmptyGrid c] -> Encoding
toEncodingList :: [NonEmptyGrid c] -> Encoding
$comitField :: forall c. ToJSON c => NonEmptyGrid c -> Bool
omitField :: NonEmptyGrid c -> Bool
ToJSON)

instance FunctorWithIndex Coords NonEmptyGrid where
  imap :: forall a b. (Coords -> a -> b) -> NonEmptyGrid a -> NonEmptyGrid b
imap Coords -> a -> b
f (NonEmptyGrid NonEmpty (NonEmpty a)
g) =
    NonEmpty (NonEmpty b) -> NonEmptyGrid b
forall c. NonEmpty (NonEmpty c) -> NonEmptyGrid c
NonEmptyGrid (NonEmpty (NonEmpty b) -> NonEmptyGrid b)
-> NonEmpty (NonEmpty b) -> NonEmptyGrid b
forall a b. (a -> b) -> a -> b
$
      (Int -> NonEmpty a -> NonEmpty b)
-> NonEmpty (NonEmpty a) -> NonEmpty (NonEmpty b)
forall a b. (Int -> a -> b) -> NonEmpty a -> NonEmpty b
forall i (f :: * -> *) a b.
FunctorWithIndex i f =>
(i -> a -> b) -> f a -> f b
imap (\Int
i -> (Int -> a -> b) -> NonEmpty a -> NonEmpty b
forall a b. (Int -> a -> b) -> NonEmpty a -> NonEmpty b
forall i (f :: * -> *) a b.
FunctorWithIndex i f =>
(i -> a -> b) -> f a -> f b
imap (\Int
j -> Coords -> a -> b
f ((Int32, Int32) -> Coords
Coords ((Int32, Int32) -> Coords) -> (Int32, Int32) -> Coords
forall a b. (a -> b) -> a -> b
$ (Int -> Int32) -> (Int, Int) -> (Int32, Int32)
forall a b. (a -> b) -> (a, a) -> (b, b)
both Int -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
i, Int
j)))) NonEmpty (NonEmpty a)
g

data Grid c
  = EmptyGrid
  | Grid (NonEmptyGrid c)
  deriving (Int -> Grid c -> ShowS
[Grid c] -> ShowS
Grid c -> String
(Int -> Grid c -> ShowS)
-> (Grid c -> String) -> ([Grid c] -> ShowS) -> Show (Grid c)
forall c. Show c => Int -> Grid c -> ShowS
forall c. Show c => [Grid c] -> ShowS
forall c. Show c => Grid c -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall c. Show c => Int -> Grid c -> ShowS
showsPrec :: Int -> Grid c -> ShowS
$cshow :: forall c. Show c => Grid c -> String
show :: Grid c -> String
$cshowList :: forall c. Show c => [Grid c] -> ShowS
showList :: [Grid c] -> ShowS
Show, Grid c -> Grid c -> Bool
(Grid c -> Grid c -> Bool)
-> (Grid c -> Grid c -> Bool) -> Eq (Grid c)
forall c. Eq c => Grid c -> Grid c -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall c. Eq c => Grid c -> Grid c -> Bool
== :: Grid c -> Grid c -> Bool
$c/= :: forall c. Eq c => Grid c -> Grid c -> Bool
/= :: Grid c -> Grid c -> Bool
Eq, (forall a b. (a -> b) -> Grid a -> Grid b)
-> (forall a b. a -> Grid b -> Grid a) -> Functor Grid
forall a b. a -> Grid b -> Grid a
forall a b. (a -> b) -> Grid a -> Grid b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Grid a -> Grid b
fmap :: forall a b. (a -> b) -> Grid a -> Grid b
$c<$ :: forall a b. a -> Grid b -> Grid a
<$ :: forall a b. a -> Grid b -> Grid a
Functor, (forall m. Monoid m => Grid m -> m)
-> (forall m a. Monoid m => (a -> m) -> Grid a -> m)
-> (forall m a. Monoid m => (a -> m) -> Grid a -> m)
-> (forall a b. (a -> b -> b) -> b -> Grid a -> b)
-> (forall a b. (a -> b -> b) -> b -> Grid a -> b)
-> (forall b a. (b -> a -> b) -> b -> Grid a -> b)
-> (forall b a. (b -> a -> b) -> b -> Grid a -> b)
-> (forall a. (a -> a -> a) -> Grid a -> a)
-> (forall a. (a -> a -> a) -> Grid a -> a)
-> (forall a. Grid a -> [a])
-> (forall a. Grid a -> Bool)
-> (forall a. Grid a -> Int)
-> (forall a. Eq a => a -> Grid a -> Bool)
-> (forall a. Ord a => Grid a -> a)
-> (forall a. Ord a => Grid a -> a)
-> (forall a. Num a => Grid a -> a)
-> (forall a. Num a => Grid a -> a)
-> Foldable Grid
forall a. Eq a => a -> Grid a -> Bool
forall a. Num a => Grid a -> a
forall a. Ord a => Grid a -> a
forall m. Monoid m => Grid m -> m
forall a. Grid a -> Bool
forall a. Grid a -> Int
forall a. Grid a -> [a]
forall a. (a -> a -> a) -> Grid a -> a
forall m a. Monoid m => (a -> m) -> Grid a -> m
forall b a. (b -> a -> b) -> b -> Grid a -> b
forall a b. (a -> b -> b) -> b -> Grid a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => Grid m -> m
fold :: forall m. Monoid m => Grid m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Grid a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Grid a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Grid a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> Grid a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> Grid a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Grid a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Grid a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Grid a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Grid a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Grid a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Grid a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> Grid a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> Grid a -> a
foldr1 :: forall a. (a -> a -> a) -> Grid a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Grid a -> a
foldl1 :: forall a. (a -> a -> a) -> Grid a -> a
$ctoList :: forall a. Grid a -> [a]
toList :: forall a. Grid a -> [a]
$cnull :: forall a. Grid a -> Bool
null :: forall a. Grid a -> Bool
$clength :: forall a. Grid a -> Int
length :: forall a. Grid a -> Int
$celem :: forall a. Eq a => a -> Grid a -> Bool
elem :: forall a. Eq a => a -> Grid a -> Bool
$cmaximum :: forall a. Ord a => Grid a -> a
maximum :: forall a. Ord a => Grid a -> a
$cminimum :: forall a. Ord a => Grid a -> a
minimum :: forall a. Ord a => Grid a -> a
$csum :: forall a. Num a => Grid a -> a
sum :: forall a. Num a => Grid a -> a
$cproduct :: forall a. Num a => Grid a -> a
product :: forall a. Num a => Grid a -> a
Foldable, Functor Grid
Foldable Grid
(Functor Grid, Foldable Grid) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> Grid a -> f (Grid b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Grid (f a) -> f (Grid a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Grid a -> m (Grid b))
-> (forall (m :: * -> *) a. Monad m => Grid (m a) -> m (Grid a))
-> Traversable Grid
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Grid (m a) -> m (Grid a)
forall (f :: * -> *) a. Applicative f => Grid (f a) -> f (Grid a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Grid a -> m (Grid b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Grid a -> f (Grid b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Grid a -> f (Grid b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Grid a -> f (Grid b)
$csequenceA :: forall (f :: * -> *) a. Applicative f => Grid (f a) -> f (Grid a)
sequenceA :: forall (f :: * -> *) a. Applicative f => Grid (f a) -> f (Grid a)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Grid a -> m (Grid b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Grid a -> m (Grid b)
$csequence :: forall (m :: * -> *) a. Monad m => Grid (m a) -> m (Grid a)
sequence :: forall (m :: * -> *) a. Monad m => Grid (m a) -> m (Grid a)
Traversable)

mkGrid :: [[a]] -> Grid a
mkGrid :: forall a. [[a]] -> Grid a
mkGrid [[a]]
rows = Grid a -> Maybe (Grid a) -> Grid a
forall a. a -> Maybe a -> a
fromMaybe Grid a
forall c. Grid c
EmptyGrid (Maybe (Grid a) -> Grid a) -> Maybe (Grid a) -> Grid a
forall a b. (a -> b) -> a -> b
$ do
  NonEmpty (NonEmpty a)
rowsNE <- [NonEmpty a] -> Maybe (NonEmpty (NonEmpty a))
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty ([NonEmpty a] -> Maybe (NonEmpty (NonEmpty a)))
-> Maybe [NonEmpty a] -> Maybe (NonEmpty (NonEmpty a))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ([a] -> Maybe (NonEmpty a)) -> [[a]] -> Maybe [NonEmpty a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM [a] -> Maybe (NonEmpty a)
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [[a]]
rows
  Grid a -> Maybe (Grid a)
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (Grid a -> Maybe (Grid a)) -> Grid a -> Maybe (Grid a)
forall a b. (a -> b) -> a -> b
$ NonEmptyGrid a -> Grid a
forall c. NonEmptyGrid c -> Grid c
Grid (NonEmptyGrid a -> Grid a) -> NonEmptyGrid a -> Grid a
forall a b. (a -> b) -> a -> b
$ NonEmpty (NonEmpty a) -> NonEmptyGrid a
forall c. NonEmpty (NonEmpty c) -> NonEmptyGrid c
NonEmptyGrid NonEmpty (NonEmpty a)
rowsNE

getNonEmptyGrid :: Grid a -> Maybe (NonEmptyGrid a)
getNonEmptyGrid :: forall a. Grid a -> Maybe (NonEmptyGrid a)
getNonEmptyGrid = \case
  Grid a
EmptyGrid -> Maybe (NonEmptyGrid a)
forall a. Maybe a
Nothing
  Grid NonEmptyGrid a
x -> NonEmptyGrid a -> Maybe (NonEmptyGrid a)
forall a. a -> Maybe a
Just NonEmptyGrid a
x

getRows :: Grid a -> [[a]]
getRows :: forall a. Grid a -> [[a]]
getRows Grid a
EmptyGrid = []
getRows (Grid (NonEmptyGrid NonEmpty (NonEmpty a)
g)) = NonEmpty [a] -> [[a]]
forall a. NonEmpty a -> [a]
NE.toList (NonEmpty [a] -> [[a]])
-> (NonEmpty (NonEmpty a) -> NonEmpty [a])
-> NonEmpty (NonEmpty a)
-> [[a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NonEmpty a -> [a]) -> NonEmpty (NonEmpty a) -> NonEmpty [a]
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
NE.map NonEmpty a -> [a]
forall a. NonEmpty a -> [a]
NE.toList (NonEmpty (NonEmpty a) -> [[a]]) -> NonEmpty (NonEmpty a) -> [[a]]
forall a b. (a -> b) -> a -> b
$ NonEmpty (NonEmpty a)
g

-- | Since the derived 'Functor' instance applies to the
-- type parameter that is nested within lists, we define
-- an explicit function for mapping over the enclosing lists.
mapRowsNE ::
  (NonEmpty (NonEmpty a) -> NonEmpty (NonEmpty b)) ->
  NonEmptyGrid a ->
  NonEmptyGrid b
mapRowsNE :: forall a b.
(NonEmpty (NonEmpty a) -> NonEmpty (NonEmpty b))
-> NonEmptyGrid a -> NonEmptyGrid b
mapRowsNE NonEmpty (NonEmpty a) -> NonEmpty (NonEmpty b)
f (NonEmptyGrid NonEmpty (NonEmpty a)
rows) = NonEmpty (NonEmpty b) -> NonEmptyGrid b
forall c. NonEmpty (NonEmpty c) -> NonEmptyGrid c
NonEmptyGrid (NonEmpty (NonEmpty b) -> NonEmptyGrid b)
-> NonEmpty (NonEmpty b) -> NonEmptyGrid b
forall a b. (a -> b) -> a -> b
$ NonEmpty (NonEmpty a) -> NonEmpty (NonEmpty b)
f NonEmpty (NonEmpty a)
rows

allMembersNE :: NonEmptyGrid c -> NonEmpty c
allMembersNE :: forall c. NonEmptyGrid c -> NonEmpty c
allMembersNE (NonEmptyGrid NonEmpty (NonEmpty c)
g) = NonEmpty (NonEmpty c) -> NonEmpty c
forall a. Semigroup a => NonEmpty a -> a
sconcat NonEmpty (NonEmpty c)
g

allMembers :: Grid a -> [a]
allMembers :: forall a. Grid a -> [a]
allMembers Grid a
EmptyGrid = []
allMembers Grid a
g = Grid a -> [a]
forall a. Grid a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList Grid a
g

mapWithCoordsNE :: (Coords -> a -> b) -> NonEmptyGrid a -> NonEmpty b
mapWithCoordsNE :: forall a b. (Coords -> a -> b) -> NonEmptyGrid a -> NonEmpty b
mapWithCoordsNE Coords -> a -> b
f = NonEmptyGrid b -> NonEmpty b
forall c. NonEmptyGrid c -> NonEmpty c
allMembersNE (NonEmptyGrid b -> NonEmpty b)
-> (NonEmptyGrid a -> NonEmptyGrid b)
-> NonEmptyGrid a
-> NonEmpty b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Coords -> a -> b) -> NonEmptyGrid a -> NonEmptyGrid b
forall a b. (Coords -> a -> b) -> NonEmptyGrid a -> NonEmptyGrid b
forall i (f :: * -> *) a b.
FunctorWithIndex i f =>
(i -> a -> b) -> f a -> f b
imap Coords -> a -> b
f

mapWithCoords :: (Coords -> a -> b) -> Grid a -> [b]
mapWithCoords :: forall a b. (Coords -> a -> b) -> Grid a -> [b]
mapWithCoords Coords -> a -> b
_ Grid a
EmptyGrid = []
mapWithCoords Coords -> a -> b
f (Grid NonEmptyGrid a
g) = NonEmpty b -> [b]
forall a. NonEmpty a -> [a]
NE.toList (NonEmpty b -> [b]) -> NonEmpty b -> [b]
forall a b. (a -> b) -> a -> b
$ (Coords -> a -> b) -> NonEmptyGrid a -> NonEmpty b
forall a b. (Coords -> a -> b) -> NonEmptyGrid a -> NonEmpty b
mapWithCoordsNE Coords -> a -> b
f NonEmptyGrid a
g

-- | Converts linked lists to vectors to facilitate
-- random access when assembling the image
gridToVec :: Grid a -> V.Vector (V.Vector a)
gridToVec :: forall a. Grid a -> Vector (Vector a)
gridToVec Grid a
g = [Vector a] -> Vector (Vector a)
forall a. [a] -> Vector a
V.fromList ([Vector a] -> Vector (Vector a))
-> ([[a]] -> [Vector a]) -> [[a]] -> Vector (Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> Vector a) -> [[a]] -> [Vector a]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> Vector a
forall a. [a] -> Vector a
V.fromList ([[a]] -> Vector (Vector a)) -> [[a]] -> Vector (Vector a)
forall a b. (a -> b) -> a -> b
$ Grid a -> [[a]]
forall a. Grid a -> [[a]]
getRows Grid a
g

instance (ToJSON a) => ToJSON (Grid a) where
  toJSON :: Grid a -> Value
toJSON Grid a
EmptyGrid = [a] -> Value
forall a. ToJSON a => a -> Value
toJSON ([] :: [a])
  toJSON (Grid NonEmptyGrid a
g) = NonEmptyGrid a -> Value
forall a. ToJSON a => a -> Value
toJSON NonEmptyGrid a
g