module ParkBench.Internal.Array1
  ( Array1,
    singleton,
    fromList,
    unsafeFromList,
    fromList1,
    toList,
    toList1,
    get,
    uncons,
    mapMaybe,
  )
where

import Data.Array (Array)
import qualified Data.Array as Array
import qualified Data.Foldable as Foldable
import qualified Data.List.NonEmpty as List (NonEmpty)
import qualified Data.List.NonEmpty as List1
import qualified Data.Maybe as Maybe
import ParkBench.Internal.Prelude

-- | A non-empty array.
data Array1 a
  = Array1 a (Array Int a)
  deriving stock (forall a. Eq a => a -> Array1 a -> Bool
forall a. Num a => Array1 a -> a
forall a. Ord a => Array1 a -> a
forall m. Monoid m => Array1 m -> m
forall a. Array1 a -> Bool
forall a. Array1 a -> Int
forall a. Array1 a -> [a]
forall a. (a -> a -> a) -> Array1 a -> a
forall m a. Monoid m => (a -> m) -> Array1 a -> m
forall b a. (b -> a -> b) -> b -> Array1 a -> b
forall a b. (a -> b -> b) -> b -> Array1 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
product :: forall a. Num a => Array1 a -> a
$cproduct :: forall a. Num a => Array1 a -> a
sum :: forall a. Num a => Array1 a -> a
$csum :: forall a. Num a => Array1 a -> a
minimum :: forall a. Ord a => Array1 a -> a
$cminimum :: forall a. Ord a => Array1 a -> a
maximum :: forall a. Ord a => Array1 a -> a
$cmaximum :: forall a. Ord a => Array1 a -> a
elem :: forall a. Eq a => a -> Array1 a -> Bool
$celem :: forall a. Eq a => a -> Array1 a -> Bool
length :: forall a. Array1 a -> Int
$clength :: forall a. Array1 a -> Int
null :: forall a. Array1 a -> Bool
$cnull :: forall a. Array1 a -> Bool
toList :: forall a. Array1 a -> [a]
$ctoList :: forall a. Array1 a -> [a]
foldl1 :: forall a. (a -> a -> a) -> Array1 a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Array1 a -> a
foldr1 :: forall a. (a -> a -> a) -> Array1 a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Array1 a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> Array1 a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Array1 a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Array1 a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Array1 a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Array1 a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Array1 a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Array1 a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Array1 a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> Array1 a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Array1 a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Array1 a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Array1 a -> m
fold :: forall m. Monoid m => Array1 m -> m
$cfold :: forall m. Monoid m => Array1 m -> m
Foldable, forall a b. a -> Array1 b -> Array1 a
forall a b. (a -> b) -> Array1 a -> Array1 b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> Array1 b -> Array1 a
$c<$ :: forall a b. a -> Array1 b -> Array1 a
fmap :: forall a b. (a -> b) -> Array1 a -> Array1 b
$cfmap :: forall a b. (a -> b) -> Array1 a -> Array1 b
Functor, Functor Array1
Foldable Array1
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 => Array1 (m a) -> m (Array1 a)
forall (f :: * -> *) a.
Applicative f =>
Array1 (f a) -> f (Array1 a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Array1 a -> m (Array1 b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Array1 a -> f (Array1 b)
sequence :: forall (m :: * -> *) a. Monad m => Array1 (m a) -> m (Array1 a)
$csequence :: forall (m :: * -> *) a. Monad m => Array1 (m a) -> m (Array1 a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Array1 a -> m (Array1 b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Array1 a -> m (Array1 b)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
Array1 (f a) -> f (Array1 a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
Array1 (f a) -> f (Array1 a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Array1 a -> f (Array1 b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Array1 a -> f (Array1 b)
Traversable)

-- | Make a singleton non-empty array.
singleton :: a -> Array1 a
singleton :: forall a. a -> Array1 a
singleton a
x =
  forall a. a -> Array Int a -> Array1 a
Array1 a
x (forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
Array.array (Int
1, Int
0) []) -- bogus bounds is the only way to make an empty array LOL

-- | Convert a list into a non-empty array.
fromList :: [a] -> Maybe (Array1 a)
fromList :: forall a. [a] -> Maybe (Array1 a)
fromList = \case
  [] -> forall a. Maybe a
Nothing
  a
x : [a]
xs -> forall a. a -> Maybe a
Just (forall a. a -> [a] -> Array1 a
fromUncons a
x [a]
xs)

-- | Convert a list into a non-empty array. Fails if the given list is empty.
unsafeFromList :: [a] -> Array1 a
unsafeFromList :: forall a. [a] -> Array1 a
unsafeFromList = \case
  [] -> forall a. HasCallStack => [Char] -> a
error [Char]
"Array1.unsafeFromList: empty list"
  a
x : [a]
xs -> forall a. a -> [a] -> Array1 a
fromUncons a
x [a]
xs

-- | Convert a non-empty list into a non-empty array.
fromList1 :: List.NonEmpty a -> Array1 a
fromList1 :: forall a. NonEmpty a -> Array1 a
fromList1 (a
x List1.:| [a]
xs) =
  forall a. a -> [a] -> Array1 a
fromUncons a
x [a]
xs

fromUncons :: a -> [a] -> Array1 a
fromUncons :: forall a. a -> [a] -> Array1 a
fromUncons a
x [a]
xs =
  forall a. a -> Array Int a -> Array1 a
Array1 a
x (forall i e. Ix i => (i, i) -> [e] -> Array i e
Array.listArray (Int
0, forall (t :: * -> *) a. Foldable t => t a -> Int
Foldable.length [a]
xs forall a. Num a => a -> a -> a
- Int
1) [a]
xs)

-- | Convert a non-empty array into a list.
toList :: Array1 a -> [a]
toList :: forall a. Array1 a -> [a]
toList =
  forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList

-- | Convert a non-empty array into a non-empty list.
toList1 :: Array1 a -> List.NonEmpty a
toList1 :: forall a. Array1 a -> NonEmpty a
toList1 (Array1 a
x Array Int a
xs) =
  a
x forall a. a -> [a] -> NonEmpty a
List1.:| forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList Array Int a
xs

-- | Get an element from a non-empty array.
get :: Int -> Array1 a -> a
get :: forall a. Int -> Array1 a -> a
get Int
i (Array1 a
x Array Int a
xs) =
  if Int
i forall a. Eq a => a -> a -> Bool
== Int
0 then a
x else Array Int a
xs forall i e. Ix i => Array i e -> i -> e
Array.! (Int
i forall a. Num a => a -> a -> a
- Int
1)

-- | Convert a non-empty array into a head element and tail array.
uncons :: Array1 a -> (a, Array Int a)
uncons :: forall a. Array1 a -> (a, Array Int a)
uncons (Array1 a
x Array Int a
xs) =
  (a
x, Array Int a
xs)

mapMaybe :: (a -> Maybe b) -> Array1 a -> Maybe (Array1 b)
mapMaybe :: forall a b. (a -> Maybe b) -> Array1 a -> Maybe (Array1 b)
mapMaybe a -> Maybe b
f =
  forall a. [a] -> Maybe (Array1 a)
fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> Maybe b) -> [a] -> [b]
Maybe.mapMaybe a -> Maybe b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList