{-# language
    BangPatterns
  , CPP
  , DeriveAnyClass
  , DeriveFunctor
  , DeriveGeneric
  , DerivingStrategies
  , InstanceSigs
  , ScopedTypeVariables
  , TemplateHaskell
  , TypeApplications
  , RankNTypes
  , FlexibleContexts
#-}

module Data.Vector.Circular.Generic
  ( -- * Types
    CircularVector(..)

    -- * Construction
    -- ** Initialization
  , singleton
  , replicate
  , replicate1
  , generate
  , generate1
  , iterateN
  , iterateN1
    -- ** Monad Initialization
  , replicateM
  , replicate1M
  , generateM
  , generate1M
  , iterateNM
  , iterateN1M
  , create
  , unsafeCreate
  , createT
  , unsafeCreateT
    -- ** Unfolding
  , unfoldr
  , unfoldr1
  , unfoldrN
  , unfoldr1N
  , unfoldrM
  , unfoldr1M
  , unfoldrNM
  , unfoldr1NM
  , constructN
  , constructrN
    -- ** Enumeration
  , enumFromN
  , enumFromN1
  , enumFromStepN
  , enumFromStepN1
  , enumFromTo
  , enumFromThenTo
    -- ** Concatenation
  , cons
  , consV
  , snoc
  , snocV
  , (Data.Vector.Circular.Generic.++)
  , concat
  , concat1
    -- ** Restricting memory usage
  , force

    -- ** Template Haskell
  -- , vec

    -- * Conversion
  , toVector
  , fromVector
  , unsafeFromVector
  , toNonEmptyVector
  , toList
  , fromList
  , fromListN
  , unsafeFromList
  , unsafeFromListN

    -- * Rotation
  , rotateLeft
  , rotateRight

    -- * Comparisons
  , equivalent
  , canonise
  , leastRotation

    -- * Folds
  , foldMap
  , foldMap'
  , foldr
  , foldl
  , foldr'
  , foldl'
  , foldr1
  , foldl1
  , foldMap1
  , foldMap1'
  , toNonEmpty

    -- * Specialized folds
  , all
  , any
  , and
  , or
  , sum
  , product
  , maximum
  , maximumBy
  , minimum
  , minimumBy
  , rotateToMinimumBy
  , rotateToMaximumBy

    -- * Elementwise operations
    -- ** Indexing
  , index
  , head
  , last

    -- ** Mapping
  , map
  , imap
  , concatMap

    -- ** Monadic mapping
  , mapM
  , imapM
  , mapM_
  , imapM_
  , forM
  , forM_

    -- ** Zipping
  , zipWith
  , zipWith3
  , zip
  , zip3

    -- ** Unzipping
  , unzip
  , unzip3

    -- ** Filtering
  , uniq
  , mapMaybe
  , imapMaybe
  , filter
  , ifilter
  , filterM
  -- , ifilterM -- Not in Data.Vector.Generic
  , takeWhile
  , dropWhile

    -- * Partitioning
  , partition
  , unstablePartition
  , span
  , break

    -- * Searching
  , elem
  , notElem
  , find
  , findIndex
  , findIndices
  , elemIndex
  , elemIndices

    -- * Permutations
  , reverse
  , backpermute
  , unsafeBackpermute

    -- * Safe destructive updates
  , modify

    -- * Monadic Sequencing
  , sequence
  , sequence_
  ) where

import qualified Control.Monad (when, forM_)
import Control.Monad.ST (ST, runST)
import Control.DeepSeq
#if MIN_VERSION_base(4,13,0)
-- import Data.Foldable (foldMap')
#endif /* MIN_VERSION_base(4,13,0) */
import Data.List.NonEmpty (NonEmpty((:|)))
import qualified Data.List.NonEmpty as NonEmptyList
import Data.Primitive.MutVar ( newMutVar, readMutVar, writeMutVar )
import Data.Vector.NonEmpty (NonEmptyVector)
import GHC.Base (modInt)
import GHC.Generics (Generic)
import Prelude hiding (head, length, last, map, concat, takeWhile
                      ,dropWhile, span, break, elem, notElem, reverse
                      ,mapM, mapM_, foldMap, foldr
                      ,foldl, foldr1, foldl1, all, any, and, or, sum
                      ,product, maximum, minimum, concatMap
                      ,zipWith, zipWith3, zip, zip3, replicate, enumFromTo
                      ,enumFromThenTo, (++), filter)
import Language.Haskell.TH.Syntax
import qualified Data.Vector.Mutable as MVector
import qualified Data.Vector.NonEmpty as NonEmpty
import qualified Data.Vector.Generic as G
import qualified Prelude
import Data.Monoid
import Data.Coerce
import Data.Maybe ( fromMaybe )

-- $setup
-- >>> import Data.Vector (Vector)
-- >>> import qualified Data.Vector


-- | A circular, immutable vector. This type is equivalent to
--   @'Data.List.cycle' xs@ for some finite, nonempty @xs@, but
--   with /O(1)/ access and /O(1)/ rotations. Indexing
--   into this type is always total.
data CircularVector v a = CircularVector
  { CircularVector v a -> v a
vector :: !(v a)
  , CircularVector v a -> Int
rotation :: {-# UNPACK #-} !Int
  }
  deriving stock
    ( Functor -- ^ since 0.1.2
    , Generic -- ^ @since 0.1.2
    , Ord     -- ^ since 0.1.2
    , Read    -- ^ since 0.1.2
    , Show    -- ^ since 0.1.2
    )
  deriving anyclass
    ( NFData -- ^ @since 0.1.2
    )

-- | @since 0.1.2
-- instance Traversable (CircularVector v) where
--   traverse :: (Applicative f) => (a -> f b) -> CircularVector a -> f (CircularVector b)
--   traverse f (CircularVector v rot) =
--     CircularVector <$> traverse f v <*> pure rot

-- | since 0.1.2
instance (G.Vector v a, Eq a) => Eq (CircularVector v a) where
  (==) :: CircularVector v a -> CircularVector v a -> Bool
  CircularVector v a
a == :: CircularVector v a -> CircularVector v a -> Bool
== CircularVector v a
b = CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v a
a v a -> v a -> Bool
forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> v a -> Bool
`G.eq` CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v a
b

-- | @since 0.1.2
-- instance Eq2 CircularVector where
--   liftEq2 :: (a -> b -> Bool) -> CircularVector v a -> CircularVector v b -> Bool
--   liftEq2 eq c0@(CircularVector x rx) c1@(CircularVector y ry)
--     | G.length x /= G.length y = False
--     | rx == ry = liftEq eq x y
--     | otherwise = getAll $ flip Prelude.foldMap [0..NonEmpty.length x-1] $ \i ->
--         All (index c0 i `eq` index c1 i)

-- | @since 0.1.2
-- instance Ord1 CircularVector where
--   liftCompare :: (a -> b -> Ordering) -> CircularVector a -> CircularVector b -> Ordering
--   liftCompare cmp (CircularVector x rx) (CircularVector y ry)
--     = liftCompare cmp x y <> compare rx ry

-- | @since 0.1.2
-- instance Show1 CircularVector where
--   liftShowsPrec :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> CircularVector a -> ShowS
--   liftShowsPrec sp sl d (CircularVector x rx) =
--     showsBinaryWith (liftShowsPrec sp sl) showsPrec "CircularVector" d x rx

-- | @since 0.1.2
-- instance Read1 CircularVector where
--   liftReadPrec rp rl = readData $
--     readBinaryWith (liftReadPrec rp rl) readPrec "CircularVector" CircularVector
--   liftReadListPrec = liftReadListPrecDefault

-- | The 'Semigroup' @('<>')@ operation behaves by un-rolling
--   the two vectors so that their rotation is 0, concatenating
--   them, returning a new vector with a 0-rotation.
--
--   since 0.1.2
instance (G.Vector v a) => Semigroup (CircularVector v a) where
  (<>) :: CircularVector v a -> CircularVector v a -> CircularVector v a
  CircularVector v a
lhs <> :: CircularVector v a -> CircularVector v a -> CircularVector v a
<> CircularVector v a
rhs = v a -> Int -> CircularVector v a
forall (v :: * -> *) a. v a -> Int -> CircularVector v a
CircularVector v a
v Int
0
    where
      szLhs :: Int
szLhs = CircularVector v a -> Int
forall (v :: * -> *) a. Vector v a => CircularVector v a -> Int
length CircularVector v a
lhs
      szRhs :: Int
szRhs = CircularVector v a -> Int
forall (v :: * -> *) a. Vector v a => CircularVector v a -> Int
length CircularVector v a
rhs
      sz :: Int
sz = Int
szLhs Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
szRhs
      v :: v a
v = Int -> (Int -> a) -> v a
forall (v :: * -> *) a. Vector v a => Int -> (Int -> a) -> v a
G.generate Int
sz
            ((Int -> a) -> v a) -> (Int -> a) -> v a
forall a b. (a -> b) -> a -> b
$ \Int
ix -> if Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
szLhs
                then CircularVector v a -> Int -> a
forall (v :: * -> *) a.
Vector v a =>
CircularVector v a -> Int -> a
index CircularVector v a
lhs Int
ix
                else CircularVector v a -> Int -> a
forall (v :: * -> *) a.
Vector v a =>
CircularVector v a -> Int -> a
index CircularVector v a
rhs (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
szLhs)
  {-# inline (<>) #-}

-- | since 0.1.2
-- instance Foldable (CircularVector v) where
--   foldMap :: Monoid m => (a -> m) -> CircularVector v a -> m
--   foldMap = Data.Vector.Circular.Generic.foldMap
--   {-# inline foldMap #-}

-- #if MIN_VERSION_base(4,13,0)
--   foldMap' :: Monoid m => (a -> m) -> CircularVector a -> m
--   foldMap' = Data.Vector.Circular.Generic.foldMap'
--   {-# inline foldMap' #-}
-- #endif /* MIN_VERSION_base(4,13,0) */

--   null :: CircularVector a -> Bool
--   null _ = False -- nonempty structure is always not null
--   {-# inline null #-}

--   length :: CircularVector a -> Int
--   length = Data.Vector.Circular.Generic.length
--   {-# inline length #-}

-- | since 0.1.2
-- instance Foldable1 CircularVector where
--   foldMap1 :: Semigroup m => (a -> m) -> CircularVector a -> m
--   foldMap1 = Data.Vector.Circular.Generic.foldMap1
--   {-# inline foldMap1 #-}

-- FIXME: This instance is probably broken.
-- | since 0.1.2
instance Lift a => Lift (CircularVector v a) where
  lift :: CircularVector v a -> Q Exp
lift CircularVector v a
c = do
    Exp
v <- [|vector c|]
    Exp
r <- [|rotation c|]
    Exp -> Q Exp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Exp -> Q Exp) -> Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$ Name -> Exp
ConE ''CircularVector
      Exp -> Exp -> Exp
`AppE` Exp
v
      Exp -> Exp -> Exp
`AppE` Exp
r
#if MIN_VERSION_template_haskell(2,16,0)
  liftTyped :: CircularVector v a -> Q (TExp (CircularVector v a))
liftTyped = Q Exp -> Q (TExp (CircularVector v a))
forall a. Q Exp -> Q (TExp a)
unsafeTExpCoerce (Q Exp -> Q (TExp (CircularVector v a)))
-> (CircularVector v a -> Q Exp)
-> CircularVector v a
-> Q (TExp (CircularVector v a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> Q Exp
forall t. Lift t => t -> Q Exp
lift
#endif /* MIN_VERSION_template_haskell(2,16,0) */

-- | Get the length of a 'CircularVector'.
--
--   since 0.1.2
length :: G.Vector v a => CircularVector v a -> Int
length :: CircularVector v a -> Int
length (CircularVector v a
v Int
_) = v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
G.length v a
v
{-# inline length #-}

-- | Lazily-accumulating monoidal fold over a 'CircularVector'.
--   since 0.1.2
foldMap :: (Monoid m, G.Vector v a) => (a -> m) -> CircularVector v a -> m
foldMap :: (a -> m) -> CircularVector v a -> m
foldMap a -> m
f = \CircularVector v a
v ->
  let len :: Int
len = CircularVector v a -> Int
forall (v :: * -> *) a. Vector v a => CircularVector v a -> Int
Data.Vector.Circular.Generic.length CircularVector v a
v
      go :: Int -> m
go !Int
ix
        | Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len = a -> m
f (CircularVector v a -> Int -> a
forall (v :: * -> *) a.
Vector v a =>
CircularVector v a -> Int -> a
index CircularVector v a
v Int
ix) m -> m -> m
forall a. Semigroup a => a -> a -> a
<> Int -> m
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
        | Bool
otherwise = m
forall a. Monoid a => a
mempty
  in Int -> m
go Int
0
{-# inline foldMap #-}



-- | Strictly-accumulating monoidal fold over a 'CircularVector'.
--
--   since 0.1.2
foldMap' :: (Monoid m, G.Vector v a) => (a -> m) -> CircularVector v a -> m
foldMap' :: (a -> m) -> CircularVector v a -> m
foldMap' a -> m
f = \CircularVector v a
v ->
  let len :: Int
len = CircularVector v a -> Int
forall (v :: * -> *) a. Vector v a => CircularVector v a -> Int
Data.Vector.Circular.Generic.length CircularVector v a
v
      go :: Int -> m -> m
go !Int
ix !m
acc
        | Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len = Int -> m -> m
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (m
acc m -> m -> m
forall a. Semigroup a => a -> a -> a
<> a -> m
f (CircularVector v a -> Int -> a
forall (v :: * -> *) a.
Vector v a =>
CircularVector v a -> Int -> a
index CircularVector v a
v Int
ix))
        | Bool
otherwise = m
acc
  in Int -> m -> m
go Int
0 m
forall a. Monoid a => a
mempty
{-# inline foldMap' #-}

(#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c)
#. :: (b -> c) -> (a -> b) -> a -> c
(#.) b -> c
_f = (a -> b) -> a -> c
coerce
{-# INLINE (#.) #-}

-- | since 0.1.2
foldr :: G.Vector v a => (a -> b -> b) -> b -> CircularVector v a -> b
foldr :: (a -> b -> b) -> b -> CircularVector v a -> b
foldr a -> b -> b
f b
z CircularVector v a
t = Endo b -> b -> b
forall a. Endo a -> a -> a
appEndo ((a -> Endo b) -> CircularVector v a -> Endo b
forall m (v :: * -> *) a.
(Monoid m, Vector v a) =>
(a -> m) -> CircularVector v a -> m
foldMap ((b -> b) -> Endo b
forall a. (a -> a) -> Endo a
Endo ((b -> b) -> Endo b) -> (a -> b -> b) -> a -> Endo b
forall b c a. Coercible b c => (b -> c) -> (a -> b) -> a -> c
#. a -> b -> b
f) CircularVector v a
t) b
z

-- -- | since 0.1.2
foldl :: G.Vector v a => (b -> a -> b) -> b -> CircularVector v a -> b
foldl :: (b -> a -> b) -> b -> CircularVector v a -> b
foldl b -> a -> b
f b
z CircularVector v a
t = Endo b -> b -> b
forall a. Endo a -> a -> a
appEndo (Dual (Endo b) -> Endo b
forall a. Dual a -> a
getDual ((a -> Dual (Endo b)) -> CircularVector v a -> Dual (Endo b)
forall m (v :: * -> *) a.
(Monoid m, Vector v a) =>
(a -> m) -> CircularVector v a -> m
foldMap (Endo b -> Dual (Endo b)
forall a. a -> Dual a
Dual (Endo b -> Dual (Endo b)) -> (a -> Endo b) -> a -> Dual (Endo b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b -> b) -> Endo b
forall a. (a -> a) -> Endo a
Endo ((b -> b) -> Endo b) -> (a -> b -> b) -> a -> Endo b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b -> a -> b) -> a -> b -> b
forall a b c. (a -> b -> c) -> b -> a -> c
flip b -> a -> b
f) CircularVector v a
t)) b
z

-- -- | since 0.1.2
foldr' :: G.Vector v a => (a -> b -> b) -> b -> CircularVector v a -> b
foldr' :: (a -> b -> b) -> b -> CircularVector v a -> b
foldr' a -> b -> b
f b
z0 CircularVector v a
xs = ((b -> b) -> a -> b -> b)
-> (b -> b) -> CircularVector v a -> b -> b
forall (v :: * -> *) a b.
Vector v a =>
(b -> a -> b) -> b -> CircularVector v a -> b
foldl (b -> b) -> a -> b -> b
forall b. (b -> b) -> a -> b -> b
f' b -> b
forall a. a -> a
id CircularVector v a
xs b
z0
  where f' :: (b -> b) -> a -> b -> b
f' b -> b
k a
x b
z = b -> b
k (b -> b) -> b -> b
forall a b. (a -> b) -> a -> b
$! a -> b -> b
f a
x b
z

-- -- | since 0.1.2
foldl' :: G.Vector v a => (b -> a -> b) -> b -> CircularVector v a -> b
foldl' :: (b -> a -> b) -> b -> CircularVector v a -> b
foldl' b -> a -> b
f b
z0 CircularVector v a
xs = (a -> (b -> b) -> b -> b)
-> (b -> b) -> CircularVector v a -> b -> b
forall (v :: * -> *) a b.
Vector v a =>
(a -> b -> b) -> b -> CircularVector v a -> b
foldr a -> (b -> b) -> b -> b
forall b. a -> (b -> b) -> b -> b
f' b -> b
forall a. a -> a
id CircularVector v a
xs b
z0
      where f' :: a -> (b -> b) -> b -> b
f' a
x b -> b
k b
z = b -> b
k (b -> b) -> b -> b
forall a b. (a -> b) -> a -> b
$! b -> a -> b
f b
z a
x

-- -- | since 0.1.2
foldr1 :: G.Vector v a => (a -> a -> a) -> CircularVector v a -> a
foldr1 :: (a -> a -> a) -> CircularVector v a -> a
foldr1 a -> a -> a
f CircularVector v a
xs = a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe (String -> a
forall a. String -> a
errorWithoutStackTrace String
"foldr1: empty structure")
                    ((a -> Maybe a -> Maybe a)
-> Maybe a -> CircularVector v a -> Maybe a
forall (v :: * -> *) a b.
Vector v a =>
(a -> b -> b) -> b -> CircularVector v a -> b
foldr a -> Maybe a -> Maybe a
mf Maybe a
forall a. Maybe a
Nothing CircularVector v a
xs)
      where
        mf :: a -> Maybe a -> Maybe a
mf a
x Maybe a
m = a -> Maybe a
forall a. a -> Maybe a
Just (case Maybe a
m of
                         Maybe a
Nothing -> a
x
                         Just a
y  -> a -> a -> a
f a
x a
y)

-- -- | since 0.1.2
foldl1 :: G.Vector v a => (a -> a -> a) -> CircularVector v a -> a
foldl1 :: (a -> a -> a) -> CircularVector v a -> a
foldl1 a -> a -> a
f CircularVector v a
xs = a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe (String -> a
forall a. String -> a
errorWithoutStackTrace String
"foldl1: empty structure")
                    ((Maybe a -> a -> Maybe a)
-> Maybe a -> CircularVector v a -> Maybe a
forall (v :: * -> *) a b.
Vector v a =>
(b -> a -> b) -> b -> CircularVector v a -> b
foldl Maybe a -> a -> Maybe a
mf Maybe a
forall a. Maybe a
Nothing CircularVector v a
xs)
      where
        mf :: Maybe a -> a -> Maybe a
mf Maybe a
m a
y = a -> Maybe a
forall a. a -> Maybe a
Just (case Maybe a
m of
                         Maybe a
Nothing -> a
y
                         Just a
x  -> a -> a -> a
f a
x a
y)

-- | since 0.1.2
toNonEmpty :: G.Vector v a => CircularVector v a -> NonEmpty a
toNonEmpty :: CircularVector v a -> NonEmpty a
toNonEmpty = [a] -> NonEmpty a
forall a. [a] -> NonEmpty a
NonEmptyList.fromList ([a] -> NonEmpty a)
-> (CircularVector v a -> [a]) -> CircularVector v a -> NonEmpty a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> [a]
forall (v :: * -> *) a. Vector v a => CircularVector v a -> [a]
toList

-- | Lazily-accumulating semigroupoidal fold over
--   a 'CircularVector'.
--
--   since 0.1.2
foldMap1 :: (G.Vector v a, Semigroup m) => (a -> m) -> CircularVector v a -> m
foldMap1 :: (a -> m) -> CircularVector v a -> m
foldMap1 a -> m
f = \CircularVector v a
v ->
  let len :: Int
len = CircularVector v a -> Int
forall (v :: * -> *) a. Vector v a => CircularVector v a -> Int
Data.Vector.Circular.Generic.length CircularVector v a
v
      go :: Int -> m
go !Int
ix
        | Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
lenInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1 = a -> m
f (CircularVector v a -> Int -> a
forall (v :: * -> *) a.
Vector v a =>
CircularVector v a -> Int -> a
index CircularVector v a
v Int
ix) m -> m -> m
forall a. Semigroup a => a -> a -> a
<> Int -> m
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
        | Bool
otherwise  = a -> m
f (CircularVector v a -> a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> a
last CircularVector v a
v)
  in Int -> m
go Int
0
{-# inline foldMap1 #-}

-- | Strictly-accumulating semigroupoidal fold over
--   a 'CircularVector'.
--
--   since 0.1.2
foldMap1' :: (G.Vector v a, Semigroup m) => (a -> m) -> CircularVector v a -> m
foldMap1' :: (a -> m) -> CircularVector v a -> m
foldMap1' a -> m
f = \CircularVector v a
v ->
  let len :: Int
len = CircularVector v a -> Int
forall (v :: * -> *) a. Vector v a => CircularVector v a -> Int
Data.Vector.Circular.Generic.length CircularVector v a
v
      go :: Int -> m -> m
go !Int
ix !m
acc
        | Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len = Int -> m -> m
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (m
acc m -> m -> m
forall a. Semigroup a => a -> a -> a
<> a -> m
f (CircularVector v a -> Int -> a
forall (v :: * -> *) a.
Vector v a =>
CircularVector v a -> Int -> a
index CircularVector v a
v Int
ix))
        | Bool
otherwise = m
acc
  in Int -> m -> m
go Int
1 (a -> m
f (CircularVector v a -> a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> a
head CircularVector v a
v))
{-# inline foldMap1' #-}

-- | /O(n)/ Construct a 'Vector' from a 'CircularVector'.
--
--   since 0.1.2
toVector :: G.Vector v a => CircularVector v a -> v a
toVector :: CircularVector v a -> v a
toVector CircularVector v a
v = Int -> (Int -> a) -> v a
forall (v :: * -> *) a. Vector v a => Int -> (Int -> a) -> v a
G.generate (CircularVector v a -> Int
forall (v :: * -> *) a. Vector v a => CircularVector v a -> Int
length CircularVector v a
v) (CircularVector v a -> Int -> a
forall (v :: * -> *) a.
Vector v a =>
CircularVector v a -> Int -> a
index CircularVector v a
v)

-- | /O(n)/ Construct a 'NonEmptyVector' from a 'CircularVector'.
--
--   @since 0.1.2
toNonEmptyVector :: G.Vector v a => CircularVector v a -> NonEmptyVector a
toNonEmptyVector :: CircularVector v a -> NonEmptyVector a
toNonEmptyVector CircularVector v a
v = Int -> (Int -> a) -> NonEmptyVector a
forall a. Int -> (Int -> a) -> NonEmptyVector a
NonEmpty.generate1 (CircularVector v a -> Int
forall (v :: * -> *) a. Vector v a => CircularVector v a -> Int
length CircularVector v a
v) (CircularVector v a -> Int -> a
forall (v :: * -> *) a.
Vector v a =>
CircularVector v a -> Int -> a
index CircularVector v a
v)

-- | /O(1)/ Construct a 'CircularVector' from a vector.
--
--   since 0.1.2
fromVector :: G.Vector v a => v a -> Maybe (CircularVector v a)
fromVector :: v a -> Maybe (CircularVector v a)
fromVector v a
v | v a -> Bool
forall (v :: * -> *) a. Vector v a => v a -> Bool
G.null v a
v = Maybe (CircularVector v a)
forall a. Maybe a
Nothing
fromVector v a
v = CircularVector v a -> Maybe (CircularVector v a)
forall a. a -> Maybe a
Just (v a -> Int -> CircularVector v a
forall (v :: * -> *) a. v a -> Int -> CircularVector v a
CircularVector v a
v Int
0)
{-# inline fromVector #-}

-- | /O(1)/ Construct a 'CircularVector' from a 'Vector'.
--
--   Calls @'error'@ if the input vector is empty.
--
--   since 0.1.2
unsafeFromVector :: G.Vector v a => v a -> CircularVector v a
unsafeFromVector :: v a -> CircularVector v a
unsafeFromVector v a
v = v a -> Int -> CircularVector v a
forall (v :: * -> *) a. v a -> Int -> CircularVector v a
CircularVector v a
v Int
0

-- | /O(n)/ Convert from a circular vector to a list.
--
--
-- >>> let nev = unsafeFromList @Vector [1..3] in toList nev
-- [1,2,3]
--
--   @since 0.1.2
toList :: G.Vector v a => CircularVector v a -> [a]
toList :: CircularVector v a -> [a]
toList = v a -> [a]
forall (v :: * -> *) a. Vector v a => v a -> [a]
G.toList (v a -> [a])
-> (CircularVector v a -> v a) -> CircularVector v a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Construct a 'CircularVector' from a list.
--
--   since 0.1.2
fromList :: G.Vector v a => [a] -> Maybe (CircularVector v a)
fromList :: [a] -> Maybe (CircularVector v a)
fromList [a]
xs = Int -> [a] -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
Int -> [a] -> Maybe (CircularVector v a)
fromListN ([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
Prelude.length [a]
xs) [a]
xs
{-# inline fromList #-}

-- | Construct a 'CircularVector' from a list with a size hint.
--
--   since 0.1.2
fromListN :: G.Vector v a => Int -> [a] -> Maybe (CircularVector v a)
fromListN :: Int -> [a] -> Maybe (CircularVector v a)
fromListN Int
n [a]
xs = v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector (Int -> [a] -> v a
forall (v :: * -> *) a. Vector v a => Int -> [a] -> v a
G.fromListN Int
n [a]
xs)
{-# inline fromListN #-}

-- | /O(n)/ Construct a 'CircularVector' from a list.
--
--   Calls @'error'@ if the input list is empty.
--
--   since 0.1.2
unsafeFromList :: G.Vector v a => [a] -> CircularVector v a
unsafeFromList :: [a] -> CircularVector v a
unsafeFromList [a]
xs = Int -> [a] -> CircularVector v a
forall (v :: * -> *) a.
Vector v a =>
Int -> [a] -> CircularVector v a
unsafeFromListN ([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
Prelude.length [a]
xs) [a]
xs

-- | /O(n)/ Construct a 'CircularVector' from a list with a size hint.
--
--   Calls @'error'@ if the input list is empty, or
--   if the size hint is @'<=' 0@.
--
--    since 0.1.2
unsafeFromListN :: G.Vector v a => Int -> [a] -> CircularVector v a
unsafeFromListN :: Int -> [a] -> CircularVector v a
unsafeFromListN Int
n [a]
xs
  | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = String -> CircularVector v a
forall a. HasCallStack => String -> a
error String
"Data.Vector.Circular.unsafeFromListN: invalid length!"
  | Bool
otherwise = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (Int -> [a] -> v a
forall (v :: * -> *) a. Vector v a => Int -> [a] -> v a
G.fromListN Int
n [a]
xs)

-- | /O(1)/ Construct a singleton 'CircularVector.
--
--   since 0.1.2
singleton :: G.Vector v a => a -> CircularVector v a
singleton :: a -> CircularVector v a
singleton = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v a -> CircularVector v a)
-> (a -> v a) -> a -> CircularVector v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> v a
forall (v :: * -> *) a. Vector v a => a -> v a
G.singleton
{-# inline singleton #-}

-- | /O(1)/ Index into a 'CircularVector'. This is always total.
--
--   since 0.1.2
index :: G.Vector v a => CircularVector v a -> Int -> a
index :: CircularVector v a -> Int -> a
index (CircularVector v a
v Int
r) = \ !Int
ix ->
  let len :: Int
len = v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
G.length v a
v
  in v a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
G.unsafeIndex v a
v (Int -> Int -> Int
unsafeMod (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
r) Int
len)
{-# inline index #-}

-- | /O(1)/ Get the first element of a 'CircularVector'. This is always total.
--
--   since 0.1.2
head :: G.Vector v a => CircularVector v a -> a
head :: CircularVector v a -> a
head CircularVector v a
v = CircularVector v a -> Int -> a
forall (v :: * -> *) a.
Vector v a =>
CircularVector v a -> Int -> a
index CircularVector v a
v Int
0
{-# inline head #-}

-- | /O(1)/ Get the last element of a 'CircularVector'. This is always total.
--
--   since 0.1.2
last :: G.Vector v a => CircularVector v a -> a
last :: CircularVector v a -> a
last CircularVector v a
v = CircularVector v a -> Int -> a
forall (v :: * -> *) a.
Vector v a =>
CircularVector v a -> Int -> a
index CircularVector v a
v (CircularVector v a -> Int
forall (v :: * -> *) a. Vector v a => CircularVector v a -> Int
Data.Vector.Circular.Generic.length CircularVector v a
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
{-# inline last #-}

-- | /O(1)/ Rotate the vector to left by @n@ number of elements.
--
--   /Note/: Right rotations start to break down due to
--   arithmetic overflow when the size of the input vector is
--   @'>' 'maxBound' @'Int'@
--
--   since 0.1.2
rotateRight :: G.Vector v a => Int -> CircularVector v a -> CircularVector v a
rotateRight :: Int -> CircularVector v a -> CircularVector v a
rotateRight Int
r' (CircularVector v a
v Int
r) = v a -> Int -> CircularVector v a
forall (v :: * -> *) a. v a -> Int -> CircularVector v a
CircularVector v a
v Int
h
  where
    len :: Int
len = v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
G.length v a
v
    h :: Int
h = Int -> Int -> Int
unsafeMod (Int
r Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int -> Int
unsafeMod Int
r' Int
len) Int
len
{-# inline rotateRight #-}

-- | /O(1)/ Rotate the vector to the left by @n@ number of elements.
--
--   /Note/: Left rotations start to break down due to
--   arithmetic underflow when the size of the input vector is
--   @'>' 'maxBound' @'Int'@
--
--   since 0.1.2
rotateLeft :: G.Vector v a => Int -> CircularVector v a -> CircularVector v a
rotateLeft :: Int -> CircularVector v a -> CircularVector v a
rotateLeft Int
r' (CircularVector v a
v Int
r) = v a -> Int -> CircularVector v a
forall (v :: * -> *) a. v a -> Int -> CircularVector v a
CircularVector v a
v Int
h
  where
    len :: Int
len = v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
G.length v a
v
    h :: Int
h = Int -> Int -> Int
unsafeMod (Int
r Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int -> Int -> Int
unsafeMod Int
r' Int
len) Int
len
{-# inline rotateLeft #-}
{-
-- | Construct a 'CircularVector' at compile-time using
--   typed Template Haskell.
--
--   since 0.1.2
vec :: (G.Vector v a, Lift a) => [a] -> Q (TExp (CircularVector v a))
vec [] = fail "Cannot create an empty CircularVector!"
vec xs =
#if MIN_VERSION_template_haskell(2,16,0)
  liftTyped (unsafeFromList xs)
#else
  unsafeTExpCoerce [|unsafeFromList xs|]
#endif /* MIN_VERSION_template_haskell(2,16,0) */
-}
-- | since 0.1.2
equivalent :: (G.Vector v a, Eq (v a), Ord a) => CircularVector v a -> CircularVector v a -> Bool
equivalent :: CircularVector v a -> CircularVector v a -> Bool
equivalent CircularVector v a
x CircularVector v a
y = CircularVector v a -> v a
forall (v :: * -> *) a. CircularVector v a -> v a
vector (CircularVector v a -> CircularVector v a
forall (v :: * -> *) a.
(Vector v a, Ord a) =>
CircularVector v a -> CircularVector v a
canonise CircularVector v a
x) v a -> v a -> Bool
forall a. Eq a => a -> a -> Bool
== CircularVector v a -> v a
forall (v :: * -> *) a. CircularVector v a -> v a
vector (CircularVector v a -> CircularVector v a
forall (v :: * -> *) a.
(Vector v a, Ord a) =>
CircularVector v a -> CircularVector v a
canonise CircularVector v a
y)

-- | since 0.1.2
canonise :: (G.Vector v a, Ord a) => CircularVector v a -> CircularVector v a
canonise :: CircularVector v a -> CircularVector v a
canonise c :: CircularVector v a
c@(CircularVector v a
v Int
r) = v a -> Int -> CircularVector v a
forall (v :: * -> *) a. v a -> Int -> CircularVector v a
CircularVector v a
v' (Int
r Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
lr)
  where
    lr :: Int
lr = NonEmptyVector a -> Int
forall a. Ord a => NonEmptyVector a -> Int
leastRotation (CircularVector v a -> NonEmptyVector a
forall (v :: * -> *) a.
Vector v a =>
CircularVector v a -> NonEmptyVector a
toNonEmptyVector CircularVector v a
c)
    v' :: v a
v' = CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector (Int -> CircularVector v a -> CircularVector v a
forall (v :: * -> *) a.
Vector v a =>
Int -> CircularVector v a -> CircularVector v a
rotateRight Int
lr (v a -> Int -> CircularVector v a
forall (v :: * -> *) a. v a -> Int -> CircularVector v a
CircularVector v a
v Int
0))

-- | since 0.1.2
leastRotation :: forall a. (Ord a) => NonEmptyVector a -> Int
leastRotation :: NonEmptyVector a -> Int
leastRotation NonEmptyVector a
v = (forall s. ST s Int) -> Int
forall a. (forall s. ST s a) -> a
runST forall s. ST s Int
go
  where
    go :: forall s. ST s Int
    go :: ST s Int
go = do
      let s :: NonEmptyVector a
s = NonEmptyVector a
v NonEmptyVector a -> NonEmptyVector a -> NonEmptyVector a
forall a. Semigroup a => a -> a -> a
<> NonEmptyVector a
v
      let len :: Int
len = NonEmptyVector a -> Int
forall a. NonEmptyVector a -> Int
NonEmpty.length NonEmptyVector a
s
      MVector s Int
f <- Int -> Int -> ST s (MVector (PrimState (ST s)) Int)
forall (m :: * -> *) a.
PrimMonad m =>
Int -> a -> m (MVector (PrimState m) a)
MVector.replicate @_ @Int Int
len (-Int
1)
      MutVar s Int
kVar <- Int -> ST s (MutVar (PrimState (ST s)) Int)
forall (m :: * -> *) a.
PrimMonad m =>
a -> m (MutVar (PrimState m) a)
newMutVar @_ @Int Int
0
      [Int] -> (Int -> ST s ()) -> ST s ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
Control.Monad.forM_ [Int
1..Int
lenInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1] ((Int -> ST s ()) -> ST s ()) -> (Int -> ST s ()) -> ST s ()
forall a b. (a -> b) -> a -> b
$ \Int
j -> do
        a
sj <- NonEmptyVector a -> Int -> ST s a
forall (m :: * -> *) a. Monad m => NonEmptyVector a -> Int -> m a
NonEmpty.indexM NonEmptyVector a
s Int
j
        Int
i0 <- MutVar (PrimState (ST s)) Int -> ST s Int
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar MutVar s Int
MutVar (PrimState (ST s)) Int
kVar ST s Int -> (Int -> ST s Int) -> ST s Int
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Int
k -> MVector (PrimState (ST s)) Int -> Int -> ST s Int
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> m a
MVector.read MVector s Int
MVector (PrimState (ST s)) Int
f (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
        let loop :: Int -> ST s Int
loop Int
i = do
              a
a <- MutVar (PrimState (ST s)) Int -> ST s Int
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar MutVar s Int
MutVar (PrimState (ST s)) Int
kVar ST s Int -> (Int -> ST s a) -> ST s a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Int
k -> NonEmptyVector a -> Int -> ST s a
forall (m :: * -> *) a. Monad m => NonEmptyVector a -> Int -> m a
NonEmpty.indexM NonEmptyVector a
s (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
              if (Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= (-Int
1) Bool -> Bool -> Bool
&& a
sj a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
a)
                then do
                  Bool -> ST s () -> ST s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
Control.Monad.when (a
sj a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
a) (MutVar (PrimState (ST s)) Int -> Int -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar MutVar s Int
MutVar (PrimState (ST s)) Int
kVar (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))
                  Int -> ST s Int
loop (Int -> ST s Int) -> ST s Int -> ST s Int
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< MVector (PrimState (ST s)) Int -> Int -> ST s Int
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> m a
MVector.read MVector s Int
MVector (PrimState (ST s)) Int
f Int
i
                else Int -> ST s Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i
        Int
i <- Int -> ST s Int
loop Int
i0
        a
a <- MutVar (PrimState (ST s)) Int -> ST s Int
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar MutVar s Int
MutVar (PrimState (ST s)) Int
kVar ST s Int -> (Int -> ST s a) -> ST s a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Int
k -> NonEmptyVector a -> Int -> ST s a
forall (m :: * -> *) a. Monad m => NonEmptyVector a -> Int -> m a
NonEmpty.indexM NonEmptyVector a
s (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
        if a
sj a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
a
          then do
            MutVar (PrimState (ST s)) Int -> ST s Int
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar MutVar s Int
MutVar (PrimState (ST s)) Int
kVar ST s Int -> (Int -> ST s ()) -> ST s ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Int
k -> Bool -> ST s () -> ST s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
Control.Monad.when (a
sj a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< (NonEmptyVector a
s NonEmptyVector a -> Int -> a
forall a. NonEmptyVector a -> Int -> a
NonEmpty.! Int
k)) (MutVar (PrimState (ST s)) Int -> Int -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar MutVar s Int
MutVar (PrimState (ST s)) Int
kVar Int
j)
            MutVar (PrimState (ST s)) Int -> ST s Int
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar MutVar s Int
MutVar (PrimState (ST s)) Int
kVar ST s Int -> (Int -> ST s ()) -> ST s ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Int
k -> MVector (PrimState (ST s)) Int -> Int -> Int -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> a -> m ()
MVector.write MVector s Int
MVector (PrimState (ST s)) Int
f (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
k) (-Int
1)
          else do
            MutVar (PrimState (ST s)) Int -> ST s Int
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar MutVar s Int
MutVar (PrimState (ST s)) Int
kVar ST s Int -> (Int -> ST s ()) -> ST s ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Int
k -> MVector (PrimState (ST s)) Int -> Int -> Int -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> a -> m ()
MVector.write MVector s Int
MVector (PrimState (ST s)) Int
f (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
k) (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
      MutVar (PrimState (ST s)) Int -> ST s Int
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar MutVar s Int
MutVar (PrimState (ST s)) Int
kVar

-- only safe if second argument is nonzero.
-- used internally for modulus operations with length.
unsafeMod :: Int -> Int -> Int
unsafeMod :: Int -> Int -> Int
unsafeMod = Int -> Int -> Int
GHC.Base.modInt
{-# inline unsafeMod #-}

-- | /O(min(m,n))/ Zip two circular vectors with the given function.
--
--   @since 0.1.2
zipWith :: (G.Vector v a, G.Vector v b, G.Vector v c) => (a -> b -> c) -> CircularVector v a -> CircularVector v b -> CircularVector v c
zipWith :: (a -> b -> c)
-> CircularVector v a -> CircularVector v b -> CircularVector v c
zipWith a -> b -> c
f CircularVector v a
a CircularVector v b
b = v c -> CircularVector v c
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v c -> CircularVector v c) -> v c -> CircularVector v c
forall a b. (a -> b) -> a -> b
$ (a -> b -> c) -> v a -> v b -> v c
forall (v :: * -> *) a b c.
(Vector v a, Vector v b, Vector v c) =>
(a -> b -> c) -> v a -> v b -> v c
G.zipWith a -> b -> c
f (CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v a
a) (CircularVector v b -> v b
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v b
b)

-- | Zip three circular vectors with the given function.
--
--   @since 0.1.2
zipWith3 :: (G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v d) => 
  (a -> b -> c -> d) -> CircularVector v a -> CircularVector v b -> CircularVector v c
  -> CircularVector v d
zipWith3 :: (a -> b -> c -> d)
-> CircularVector v a
-> CircularVector v b
-> CircularVector v c
-> CircularVector v d
zipWith3 a -> b -> c -> d
f CircularVector v a
a CircularVector v b
b CircularVector v c
c = v d -> CircularVector v d
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v d -> CircularVector v d) -> v d -> CircularVector v d
forall a b. (a -> b) -> a -> b
$ (a -> b -> c -> d) -> v a -> v b -> v c -> v d
forall (v :: * -> *) a b c d.
(Vector v a, Vector v b, Vector v c, Vector v d) =>
(a -> b -> c -> d) -> v a -> v b -> v c -> v d
G.zipWith3 a -> b -> c -> d
f (CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v a
a) (CircularVector v b -> v b
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v b
b) (CircularVector v c -> v c
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v c
c)

-- | /O(min(n,m))/ Elementwise pairing of circular vector elements.
--   This is a special case of 'zipWith' where the function argument is '(,)'
--
--   @since 0.1.2
zip :: (G.Vector v a, G.Vector v b, G.Vector v (a,b)) => CircularVector v a -> CircularVector v b -> CircularVector v (a,b)
zip :: CircularVector v a -> CircularVector v b -> CircularVector v (a, b)
zip CircularVector v a
a CircularVector v b
b = v (a, b) -> CircularVector v (a, b)
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v (a, b) -> CircularVector v (a, b))
-> v (a, b) -> CircularVector v (a, b)
forall a b. (a -> b) -> a -> b
$ v a -> v b -> v (a, b)
forall (v :: * -> *) a b.
(Vector v a, Vector v b, Vector v (a, b)) =>
v a -> v b -> v (a, b)
G.zip (CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v a
a) (CircularVector v b -> v b
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v b
b)

-- | Zip together three circular vectors.
--
--   @since 0.1.2
zip3 :: (G.Vector v a, G.Vector v b, G.Vector v c, G.Vector v (a,b,c)) =>
  CircularVector v a -> CircularVector v b -> CircularVector v c -> CircularVector v (a,b,c)
zip3 :: CircularVector v a
-> CircularVector v b
-> CircularVector v c
-> CircularVector v (a, b, c)
zip3 CircularVector v a
a CircularVector v b
b CircularVector v c
c = v (a, b, c) -> CircularVector v (a, b, c)
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v (a, b, c) -> CircularVector v (a, b, c))
-> v (a, b, c) -> CircularVector v (a, b, c)
forall a b. (a -> b) -> a -> b
$ v a -> v b -> v c -> v (a, b, c)
forall (v :: * -> *) a b c.
(Vector v a, Vector v b, Vector v c, Vector v (a, b, c)) =>
v a -> v b -> v c -> v (a, b, c)
G.zip3 (CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v a
a) (CircularVector v b -> v b
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v b
b) (CircularVector v c -> v c
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v c
c)

-- | /O(n)/ Reverse a circular vector.
--
--   @since 0.1.2
reverse :: G.Vector v a => CircularVector v a -> CircularVector v a
reverse :: CircularVector v a -> CircularVector v a
reverse = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v a -> CircularVector v a)
-> (CircularVector v a -> v a)
-> CircularVector v a
-> CircularVector v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v a -> v a
forall (v :: * -> *) a. Vector v a => v a -> v a
G.reverse (v a -> v a)
-> (CircularVector v a -> v a) -> CircularVector v a -> v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Rotate to the minimum element of the circular vector according to the
--   given comparison function.
--
--   @since 0.1.2
rotateToMinimumBy :: G.Vector v a => (a -> a -> Ordering) -> CircularVector v a -> CircularVector v a
rotateToMinimumBy :: (a -> a -> Ordering) -> CircularVector v a -> CircularVector v a
rotateToMinimumBy a -> a -> Ordering
f (CircularVector v a
v Int
_rot) =
  v a -> Int -> CircularVector v a
forall (v :: * -> *) a. v a -> Int -> CircularVector v a
CircularVector v a
v ((a -> a -> Ordering) -> v a -> Int
forall (v :: * -> *) a.
Vector v a =>
(a -> a -> Ordering) -> v a -> Int
G.minIndexBy a -> a -> Ordering
f v a
v)

-- | /O(n)/ Rotate to the maximum element of the circular vector according to the
--   given comparison function.
--
--   @since 0.1.2
rotateToMaximumBy :: G.Vector v a => (a -> a -> Ordering) -> CircularVector v a -> CircularVector v a
rotateToMaximumBy :: (a -> a -> Ordering) -> CircularVector v a -> CircularVector v a
rotateToMaximumBy a -> a -> Ordering
f (CircularVector v a
v Int
_rot) =
  v a -> Int -> CircularVector v a
forall (v :: * -> *) a. v a -> Int -> CircularVector v a
CircularVector v a
v ((a -> a -> Ordering) -> v a -> Int
forall (v :: * -> *) a.
Vector v a =>
(a -> a -> Ordering) -> v a -> Int
G.maxIndexBy a -> a -> Ordering
f v a
v)

-- | /O(n)/ Check if all elements satisfy the predicate.
--
--   @since 0.1.2
all :: G.Vector v a => (a -> Bool) -> CircularVector v a -> Bool
all :: (a -> Bool) -> CircularVector v a -> Bool
all a -> Bool
f = (a -> Bool) -> v a -> Bool
forall (v :: * -> *) a. Vector v a => (a -> Bool) -> v a -> Bool
G.all a -> Bool
f (v a -> Bool)
-> (CircularVector v a -> v a) -> CircularVector v a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. CircularVector v a -> v a
vector

-- | /O(n)/ Check if any element satisfies the predicate.
--
--   @since 0.1.2
any :: G.Vector v a => (a -> Bool) -> CircularVector v a -> Bool
any :: (a -> Bool) -> CircularVector v a -> Bool
any a -> Bool
f = (a -> Bool) -> v a -> Bool
forall (v :: * -> *) a. Vector v a => (a -> Bool) -> v a -> Bool
G.any a -> Bool
f (v a -> Bool)
-> (CircularVector v a -> v a) -> CircularVector v a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. CircularVector v a -> v a
vector

-- | /O(n)/ Check if all elements are True.
--
--   @since 0.1.2
and :: G.Vector v Bool => CircularVector v Bool -> Bool
and :: CircularVector v Bool -> Bool
and = v Bool -> Bool
forall (v :: * -> *). Vector v Bool => v Bool -> Bool
G.and (v Bool -> Bool)
-> (CircularVector v Bool -> v Bool)
-> CircularVector v Bool
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v Bool -> v Bool
forall (v :: * -> *) a. CircularVector v a -> v a
vector

-- | /O(n)/ Check if any element is True.
--
--   @since 0.1.2
or :: G.Vector v Bool => CircularVector v Bool -> Bool
or :: CircularVector v Bool -> Bool
or = v Bool -> Bool
forall (v :: * -> *). Vector v Bool => v Bool -> Bool
G.or (v Bool -> Bool)
-> (CircularVector v Bool -> v Bool)
-> CircularVector v Bool
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v Bool -> v Bool
forall (v :: * -> *) a. CircularVector v a -> v a
vector

-- | /O(n)/ Compute the sum of the elements.
--
--   @since 0.1.2
sum :: (G.Vector v a, Num a) => CircularVector v a -> a
sum :: CircularVector v a -> a
sum = v a -> a
forall (v :: * -> *) a. (Vector v a, Num a) => v a -> a
G.sum (v a -> a)
-> (CircularVector v a -> v a) -> CircularVector v a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. CircularVector v a -> v a
vector

-- | /O(n)/ Compute the product of the elements.
--
--   @since 0.1.2
product :: (G.Vector v a, Num a) => CircularVector v a -> a
product :: CircularVector v a -> a
product = v a -> a
forall (v :: * -> *) a. (Vector v a, Num a) => v a -> a
G.sum (v a -> a)
-> (CircularVector v a -> v a) -> CircularVector v a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. CircularVector v a -> v a
vector

-- | /O(n)/ Yield the maximum element of the circular vector.
--
--   @since 0.1.2
maximum :: (G.Vector v a, Ord a) => CircularVector v a -> a
maximum :: CircularVector v a -> a
maximum = v a -> a
forall (v :: * -> *) a. (Vector v a, Ord a) => v a -> a
G.maximum (v a -> a)
-> (CircularVector v a -> v a) -> CircularVector v a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. CircularVector v a -> v a
vector

-- | /O(n)/ Yield the maximum element of a circular vector according to the
--   given comparison function.
--
--   @since 0.1.2
maximumBy :: G.Vector v a => (a -> a -> Ordering) -> CircularVector v a -> a
maximumBy :: (a -> a -> Ordering) -> CircularVector v a -> a
maximumBy a -> a -> Ordering
f = (a -> a -> Ordering) -> v a -> a
forall (v :: * -> *) a.
Vector v a =>
(a -> a -> Ordering) -> v a -> a
G.maximumBy a -> a -> Ordering
f (v a -> a)
-> (CircularVector v a -> v a) -> CircularVector v a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. CircularVector v a -> v a
vector

-- | /O(n)/ Yield the minimum element of the circular vector.
--
--   @since 0.1.2
minimum :: (G.Vector v a, Ord a) => CircularVector v a -> a
minimum :: CircularVector v a -> a
minimum = v a -> a
forall (v :: * -> *) a. (Vector v a, Ord a) => v a -> a
G.minimum (v a -> a)
-> (CircularVector v a -> v a) -> CircularVector v a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. CircularVector v a -> v a
vector

-- | /O(n)/ Yield the minimum element of a circular vector according to the
--   given comparison function.
--
--   @since 0.1.2
minimumBy :: G.Vector v a => (a -> a -> Ordering) -> CircularVector v a -> a
minimumBy :: (a -> a -> Ordering) -> CircularVector v a -> a
minimumBy a -> a -> Ordering
f = (a -> a -> Ordering) -> v a -> a
forall (v :: * -> *) a.
Vector v a =>
(a -> a -> Ordering) -> v a -> a
G.minimumBy a -> a -> Ordering
f (v a -> a)
-> (CircularVector v a -> v a) -> CircularVector v a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. CircularVector v a -> v a
vector

-- | /O(n)/ Circular vector of the given length with the same value in
-- each position.
--
-- When given a index n <= 0, then 'Nothing' is returned, otherwise 'Just'.
--
--   @since 0.1.2
--
-- >>> replicate @Vector 3 "a"
-- Just (CircularVector {vector = ["a","a","a"], rotation = 0})
--
-- >>> replicate @Vector 0 "a"
-- Nothing
--
replicate :: G.Vector v a => Int -> a -> Maybe (CircularVector v a)
replicate :: Int -> a -> Maybe (CircularVector v a)
replicate Int
n a
a = v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector (Int -> a -> v a
forall (v :: * -> *) a. Vector v a => Int -> a -> v a
G.replicate Int
n a
a)

-- | /O(n)/ Circular vector of the given length with the same value in
-- each position.
--
-- This variant takes @max n 1@ for the supplied length parameter.
--
--   @since 0.1.2
--
-- >>> toList $ replicate1 @Vector 3 "a"
-- ["a","a","a"]
--
-- >>> toList $ replicate1 @Vector 0 "a"
-- ["a"]
--
-- >>> toList $ replicate1 @Vector (-1) "a"
-- ["a"]
replicate1 :: G.Vector v a => Int -> a -> CircularVector v a
replicate1 :: Int -> a -> CircularVector v a
replicate1 Int
n a
a = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (Int -> a -> v a
forall (v :: * -> *) a. Vector v a => Int -> a -> v a
G.replicate (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
n Int
1) a
a)

-- | /O(n)/ Construct a circular vector of the given length by applying the function to
-- each index.
--
-- When given a index n <= 0, then 'Nothing' is returned, otherwise 'Just'.
--
--   @since 0.1.2
--
-- >>> let f 0 = "a"; f _ = "k"; f :: Int -> String
--
-- >>> generate @Vector 1 f
-- Just (CircularVector {vector = ["a"], rotation = 0})
--
-- >>> generate @Vector 0 f
-- Nothing
--
-- >>> generate @Vector 2 f
-- Just (CircularVector {vector = ["a","k"], rotation = 0})
--
generate :: G.Vector v a => Int -> (Int -> a) -> Maybe (CircularVector v a)
generate :: Int -> (Int -> a) -> Maybe (CircularVector v a)
generate Int
n Int -> a
f = v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector (Int -> (Int -> a) -> v a
forall (v :: * -> *) a. Vector v a => Int -> (Int -> a) -> v a
G.generate Int
n Int -> a
f)

-- | /O(n)/ Construct a circular vector of the given length by applying the function to
-- each index.
--
-- This variant takes @max n 1@ for the supplied length parameter.
--
--   @since 0.1.2
--
-- >>> let f 0 = "a"; f _ = "k"; f :: Int -> String
--
-- >>> toList $ generate1 @Vector 2 f
-- ["a","k"]
--
-- >>> toList $ generate1 @Vector 0 f
-- ["a"]
--
-- >>> toList $ generate1 @Vector (-1) f
-- ["a"]
--
generate1 :: G.Vector v a => Int -> (Int -> a) -> CircularVector v a
generate1 :: Int -> (Int -> a) -> CircularVector v a
generate1 Int
n Int -> a
f = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (Int -> (Int -> a) -> v a
forall (v :: * -> *) a. Vector v a => Int -> (Int -> a) -> v a
G.generate (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
n Int
1) Int -> a
f)

-- | /O(n)/ Apply function n times to value. Zeroth element is original value.
--
-- When given a index n <= 0, then 'Nothing' is returned, otherwise 'Just'.
--
--   @since 0.1.2
--
-- >>> iterateN @Vector 3 (+1) 0
-- Just (CircularVector {vector = [0,1,2], rotation = 0})
--
-- >>> iterateN @Vector 0 (+1) 0
-- Nothing
--
-- >>> iterateN @Vector (-1) (+1) 0
-- Nothing
--
iterateN :: G.Vector v a => Int -> (a -> a) -> a -> Maybe (CircularVector v a)
iterateN :: Int -> (a -> a) -> a -> Maybe (CircularVector v a)
iterateN Int
n a -> a
f a
a = v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector (Int -> (a -> a) -> a -> v a
forall (v :: * -> *) a. Vector v a => Int -> (a -> a) -> a -> v a
G.iterateN Int
n a -> a
f a
a)

-- | /O(n)/ Apply function n times to value. Zeroth element is original value.
--
-- This variant takes @max n 1@ for the supplied length parameter.
--
--   @since 0.1.2
--
-- >>> iterateN1 @Vector 3 (+1) 0
-- CircularVector {vector = [0,1,2], rotation = 0}
--
-- >>> iterateN1 @Vector 0 (+1) 0
-- CircularVector {vector = [0], rotation = 0}
--
-- >>> iterateN1 @Vector (-1) (+1) 0
-- CircularVector {vector = [0], rotation = 0}
--
iterateN1 :: G.Vector v a => Int -> (a -> a) -> a -> CircularVector v a
iterateN1 :: Int -> (a -> a) -> a -> CircularVector v a
iterateN1 Int
n a -> a
f a
a = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (Int -> (a -> a) -> a -> v a
forall (v :: * -> *) a. Vector v a => Int -> (a -> a) -> a -> v a
G.iterateN (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
n Int
1) a -> a
f a
a)

-- | /O(n)/ Execute the monadic action the given number of times and store
-- the results in a circular vector.
--
-- When given a index n <= 0, then 'Nothing' is returned, otherwise 'Just'.
--
--   @since 0.1.2
--
-- >>> replicateM @Maybe @Vector 3 (Just "a")
-- Just (Just (CircularVector {vector = ["a","a","a"], rotation = 0}))
--
-- >>> replicateM @Maybe @Vector 3 Nothing
-- Nothing
--
-- >>> replicateM @Maybe @Vector 0 (Just "a")
-- Just Nothing
--
-- >>> replicateM @Maybe @Vector (-1) (Just "a")
-- Just Nothing
--
replicateM :: (Monad m, G.Vector v a) => Int -> m a -> m (Maybe (CircularVector v a))
replicateM :: Int -> m a -> m (Maybe (CircularVector v a))
replicateM Int
n m a
a = (v a -> Maybe (CircularVector v a))
-> m (v a) -> m (Maybe (CircularVector v a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector (Int -> m a -> m (v a)
forall (m :: * -> *) (v :: * -> *) a.
(Monad m, Vector v a) =>
Int -> m a -> m (v a)
G.replicateM Int
n m a
a)

-- | /O(n)/ Execute the monadic action the given number of times and store
-- the results in a circular vector.
--
-- This variant takes @max n 1@ for the supplied length parameter.
--
--   @since 0.1.2
--
-- >>> replicate1M @Maybe @Vector 3 (Just "a")
-- Just (CircularVector {vector = ["a","a","a"], rotation = 0})
--
-- >>> replicate1M @Maybe @Vector 3 Nothing
-- Nothing
--
-- >>> replicate1M @Maybe @Vector 0 (Just "a")
-- Just (CircularVector {vector = ["a"], rotation = 0})
--
-- >>> replicate1M @Maybe @Vector (-1) (Just "a")
-- Just (CircularVector {vector = ["a"], rotation = 0})
--
replicate1M :: (Monad m, G.Vector v a) => Int -> m a -> m (CircularVector v a)
replicate1M :: Int -> m a -> m (CircularVector v a)
replicate1M Int
n m a
a = (v a -> CircularVector v a) -> m (v a) -> m (CircularVector v a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (Int -> m a -> m (v a)
forall (m :: * -> *) (v :: * -> *) a.
(Monad m, Vector v a) =>
Int -> m a -> m (v a)
G.replicateM (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
n Int
1) m a
a)

-- | /O(n)/ Construct a circular vector of the given length by applying the monadic
-- action to each index
--
-- When given a index n <= 0, then 'Nothing' is returned, otherwise 'Just'.
--
--   @since 0.1.2
--
-- >>> generateM @[] @Vector 3 (\i -> if i < 1 then ["a"] else ["b"])
-- [Just (CircularVector {vector = ["a","b","b"], rotation = 0})]
--
-- >>> generateM @[] @Vector @Int 3 (const [])
-- []
--
-- >>> generateM @[] @Vector @Int 0 (const [1])
-- [Nothing]
--
-- >>> generateM @Maybe @Vector @Int (-1) (const Nothing)
-- Just Nothing
--
generateM :: (Monad m, G.Vector v a) => Int -> (Int -> m a) -> m (Maybe (CircularVector v a))
generateM :: Int -> (Int -> m a) -> m (Maybe (CircularVector v a))
generateM Int
n Int -> m a
f = (v a -> Maybe (CircularVector v a))
-> m (v a) -> m (Maybe (CircularVector v a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector (Int -> (Int -> m a) -> m (v a)
forall (m :: * -> *) (v :: * -> *) a.
(Monad m, Vector v a) =>
Int -> (Int -> m a) -> m (v a)
G.generateM Int
n Int -> m a
f)

-- | /O(n)/ Construct a circular vector of the given length by applying the monadic
-- action to each index
--
-- This variant takes @max n 1@ for the supplied length parameter.
--
--   @since 0.1.2
--
-- >>> generate1M @Maybe @Vector 3 (\i -> if i < 1 then Just "a" else Just "b")
-- Just (CircularVector {vector = ["a","b","b"], rotation = 0})
--
-- >>> generate1M @[] @Vector 3 (const [])
-- []
--
-- >>> generate1M @Maybe @Vector 0 (const $ Just 1)
-- Just (CircularVector {vector = [1], rotation = 0})
--
-- >>> generate1M @Maybe @Vector (-1) (const Nothing)
-- Nothing
--
generate1M :: (Monad m, G.Vector v a) => Int -> (Int -> m a) -> m (CircularVector v a)
generate1M :: Int -> (Int -> m a) -> m (CircularVector v a)
generate1M Int
n Int -> m a
f = (v a -> CircularVector v a) -> m (v a) -> m (CircularVector v a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (Int -> (Int -> m a) -> m (v a)
forall (m :: * -> *) (v :: * -> *) a.
(Monad m, Vector v a) =>
Int -> (Int -> m a) -> m (v a)
G.generateM (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
n Int
1) Int -> m a
f)

-- | /O(n)/ Apply monadic function n times to value. Zeroth element is
-- original value.
--
-- When given a index n <= 0, then 'Nothing' is returned, otherwise 'Just'.
--
--   @since 0.1.2
--
-- >>> iterateNM @Maybe @Vector 3 return "a"
-- Just (Just (CircularVector {vector = ["a","a","a"], rotation = 0}))
--
-- >>> iterateNM @Maybe @Vector 3 (const Nothing) "a"
-- Nothing
--
-- >>> iterateNM @Maybe @Vector 0 return "a"
-- Just Nothing
--
iterateNM :: (Monad m, G.Vector v a) => Int -> (a -> m a) -> a -> m (Maybe (CircularVector v a))
iterateNM :: Int -> (a -> m a) -> a -> m (Maybe (CircularVector v a))
iterateNM Int
n a -> m a
f a
a = (v a -> Maybe (CircularVector v a))
-> m (v a) -> m (Maybe (CircularVector v a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector (Int -> (a -> m a) -> a -> m (v a)
forall (m :: * -> *) (v :: * -> *) a.
(Monad m, Vector v a) =>
Int -> (a -> m a) -> a -> m (v a)
G.iterateNM Int
n a -> m a
f a
a)

-- | /O(n)/ Apply monadic function n times to value. Zeroth element is
-- original value.
--
-- This variant takes @max n 1@ for the supplied length parameter.
--
--   @since 0.1.2
--
-- >>> iterateN1M @Maybe @Vector 3 return "a"
-- Just (CircularVector {vector = ["a","a","a"], rotation = 0})
--
-- >>> iterateN1M @Maybe @Vector 3 (const Nothing) "a"
-- Nothing
--
-- >>> iterateN1M @Maybe @Vector 0 return "a"
-- Just (CircularVector {vector = ["a"], rotation = 0})
--
-- >>> iterateN1M @Maybe @Vector (-1) return "a"
-- Just (CircularVector {vector = ["a"], rotation = 0})
--
iterateN1M :: (Monad m, G.Vector v a) => Int -> (a -> m a) -> a -> m (CircularVector v a)
iterateN1M :: Int -> (a -> m a) -> a -> m (CircularVector v a)
iterateN1M Int
n a -> m a
f a
a = (v a -> CircularVector v a) -> m (v a) -> m (CircularVector v a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (Int -> (a -> m a) -> a -> m (v a)
forall (m :: * -> *) (v :: * -> *) a.
(Monad m, Vector v a) =>
Int -> (a -> m a) -> a -> m (v a)
G.iterateNM (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
n Int
1) a -> m a
f a
a)

-- | Execute the monadic action and freeze the resulting circular vector.
--
--   @since 0.1.2
create :: G.Vector v a => (forall s. ST s (G.Mutable v s a)) -> Maybe (CircularVector v a)
create :: (forall s. ST s (Mutable v s a)) -> Maybe (CircularVector v a)
create forall s. ST s (Mutable v s a)
p = v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector ((forall s. ST s (Mutable v s a)) -> v a
forall (v :: * -> *) a.
Vector v a =>
(forall s. ST s (Mutable v s a)) -> v a
G.create forall s. ST s (Mutable v s a)
p)

-- | Execute the monadic action and freeze the resulting circular vector,
-- bypassing emptiness checks.
--
-- The onus is on the caller to guarantee the created vector is non-empty.
--
--   @since 0.1.2
unsafeCreate :: G.Vector v a => (forall s. ST s (G.Mutable v s a)) -> CircularVector v a
unsafeCreate :: (forall s. ST s (Mutable v s a)) -> CircularVector v a
unsafeCreate forall s. ST s (Mutable v s a)
p = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector ((forall s. ST s (Mutable v s a)) -> v a
forall (v :: * -> *) a.
Vector v a =>
(forall s. ST s (Mutable v s a)) -> v a
G.create forall s. ST s (Mutable v s a)
p)

-- | Execute the monadic action and freeze the resulting circular vector.
--
--   @since 0.1.2
createT
    :: (Traversable t, G.Vector v a)
    => (forall s. ST s (t (G.Mutable v s a)))
    -> t (Maybe (CircularVector v a))
createT :: (forall s. ST s (t (Mutable v s a)))
-> t (Maybe (CircularVector v a))
createT forall s. ST s (t (Mutable v s a))
p = (v a -> Maybe (CircularVector v a))
-> t (v a) -> t (Maybe (CircularVector v a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector ((forall s. ST s (t (Mutable v s a))) -> t (v a)
forall (f :: * -> *) (v :: * -> *) a.
(Traversable f, Vector v a) =>
(forall s. ST s (f (Mutable v s a))) -> f (v a)
G.createT forall s. ST s (t (Mutable v s a))
p)

-- | Execute the monadic action and freeze the resulting circular vector.
--
-- The onus is on the caller to guarantee the created vector is non-empty.
--
--   @since 0.1.2
unsafeCreateT
    :: (Traversable t, G.Vector v a)
    => (forall s. ST s (t (G.Mutable v s a)))
    -> t (CircularVector v a)
unsafeCreateT :: (forall s. ST s (t (Mutable v s a))) -> t (CircularVector v a)
unsafeCreateT forall s. ST s (t (Mutable v s a))
p = (v a -> CircularVector v a) -> t (v a) -> t (CircularVector v a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector ((forall s. ST s (t (Mutable v s a))) -> t (v a)
forall (f :: * -> *) (v :: * -> *) a.
(Traversable f, Vector v a) =>
(forall s. ST s (f (Mutable v s a))) -> f (v a)
G.createT forall s. ST s (t (Mutable v s a))
p)

-- | /O(n)/ Construct a circular vector by repeatedly applying the
-- generator function to a seed. The generator function yields 'Just' the
-- next element and the new seed or 'Nothing' if there are no more
-- elements.
--
-- If an unfold does not create meaningful values, 'Nothing' is
-- returned. Otherwise, 'Just' containing a circular vector is returned.
--
--   @since 0.1.2
--
-- >>> unfoldr @Vector (\b -> case b of "a" -> Just ("a", "b"); _ ->  Nothing) "a"
-- Just (CircularVector {vector = ["a"], rotation = 0})
--
-- >>> unfoldr @Vector (const Nothing) "a"
-- Nothing
--
unfoldr :: G.Vector v a => (b -> Maybe (a, b)) -> b -> Maybe (CircularVector v a)
unfoldr :: (b -> Maybe (a, b)) -> b -> Maybe (CircularVector v a)
unfoldr b -> Maybe (a, b)
f b
b = v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector ((b -> Maybe (a, b)) -> b -> v a
forall (v :: * -> *) a b.
Vector v a =>
(b -> Maybe (a, b)) -> b -> v a
G.unfoldr b -> Maybe (a, b)
f b
b)

-- | /O(n)/ Construct a circular vector by repeatedly applying the
-- generator function to a seed and a first element.
--
-- This variant of 'unfoldr' guarantees the resulting vector is non-
-- empty by supplying an initial element @a@.
--
--   @since 0.1.2
--
-- >>> unfoldr1 @Vector (\b -> case b of "a" -> Just ("a", "b"); _ ->  Nothing) "first" "a"
-- CircularVector {vector = ["first","a"], rotation = 0}
--
-- >>> unfoldr1 @Vector (const Nothing) "first" "a"
-- CircularVector {vector = ["first"], rotation = 0}
--
unfoldr1 :: G.Vector v a => (b -> Maybe (a, b)) -> a -> b -> CircularVector v a
unfoldr1 :: (b -> Maybe (a, b)) -> a -> b -> CircularVector v a
unfoldr1 b -> Maybe (a, b)
f a
a b
b = a -> CircularVector v a -> CircularVector v a
forall (v :: * -> *) a.
Vector v a =>
a -> CircularVector v a -> CircularVector v a
cons a
a (v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector ((b -> Maybe (a, b)) -> b -> v a
forall (v :: * -> *) a b.
Vector v a =>
(b -> Maybe (a, b)) -> b -> v a
G.unfoldr b -> Maybe (a, b)
f b
b))

-- | /O(n)/ Construct a circular vector with at most n elements by repeatedly
-- applying the generator function to a seed. The generator function yields
-- 'Just' the next element and the new seed or 'Nothing' if there are no
-- more elements.
--
-- If an unfold does not create meaningful values, 'Nothing' is
-- returned. Otherwise, 'Just' containing a circular vector is returned.
--
--   @since 0.1.2
--
-- >>> unfoldrN @Vector 3 (\b -> Just (b+1, b+1)) 0
-- Just (CircularVector {vector = [1,2,3], rotation = 0})
--
-- >>> unfoldrN @Vector 3 (const Nothing) 0
-- Nothing
--
-- >>> unfoldrN @Vector 0 (\b -> Just (b+1, b+1)) 0
-- Nothing
--
unfoldrN :: G.Vector v a => Int -> (b -> Maybe (a, b)) -> b -> Maybe (CircularVector v a)
unfoldrN :: Int -> (b -> Maybe (a, b)) -> b -> Maybe (CircularVector v a)
unfoldrN Int
n b -> Maybe (a, b)
f b
b = v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector (Int -> (b -> Maybe (a, b)) -> b -> v a
forall (v :: * -> *) a b.
Vector v a =>
Int -> (b -> Maybe (a, b)) -> b -> v a
G.unfoldrN Int
n b -> Maybe (a, b)
f b
b)

-- | /O(n)/ Construct a circular vector with at most n elements by repeatedly
-- applying the generator function to a seed. The generator function yields
-- 'Just' the next element and the new seed or 'Nothing' if there are no
-- more elements.
--
-- This variant of 'unfoldrN' guarantees the resulting vector is non-
-- empty by supplying an initial element @a@.
--
--   @since 0.1.2
--
-- >>> unfoldr1N @Vector 3 (\b -> Just (b+1, b+1)) 0 0
-- CircularVector {vector = [0,1,2,3], rotation = 0}
--
-- >>> unfoldr1N @Vector 3 (const Nothing) 0 0
-- CircularVector {vector = [0], rotation = 0}
--
-- >>> unfoldr1N @Vector 0 (\b -> Just (b+1, b+1)) 0 0
-- CircularVector {vector = [0], rotation = 0}
--
unfoldr1N
    :: G.Vector v a
    => Int
    -> (b -> Maybe (a, b))
    -> a
    -> b
    -> CircularVector v a
unfoldr1N :: Int -> (b -> Maybe (a, b)) -> a -> b -> CircularVector v a
unfoldr1N Int
n b -> Maybe (a, b)
f a
a b
b = a -> CircularVector v a -> CircularVector v a
forall (v :: * -> *) a.
Vector v a =>
a -> CircularVector v a -> CircularVector v a
cons a
a (v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (Int -> (b -> Maybe (a, b)) -> b -> v a
forall (v :: * -> *) a b.
Vector v a =>
Int -> (b -> Maybe (a, b)) -> b -> v a
G.unfoldrN Int
n b -> Maybe (a, b)
f b
b))

-- | /O(n)/ Construct a circular vector by repeatedly applying the monadic generator
-- function to a seed. The generator function yields Just the next element
-- and the new seed or Nothing if there are no more elements.
--
-- If an unfold does not create meaningful values, 'Nothing' is
-- returned. Otherwise, 'Just' containing a circular vector is returned.
--
--   @since 0.1.2
unfoldrM
    :: (Monad m, G.Vector v a)
    => (b -> m (Maybe (a, b)))
    -> b
    -> m (Maybe (CircularVector v a))
unfoldrM :: (b -> m (Maybe (a, b))) -> b -> m (Maybe (CircularVector v a))
unfoldrM b -> m (Maybe (a, b))
f b
b = (v a -> Maybe (CircularVector v a))
-> m (v a) -> m (Maybe (CircularVector v a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector ((b -> m (Maybe (a, b))) -> b -> m (v a)
forall (m :: * -> *) (v :: * -> *) a b.
(Monad m, Vector v a) =>
(b -> m (Maybe (a, b))) -> b -> m (v a)
G.unfoldrM b -> m (Maybe (a, b))
f b
b)

-- | /O(n)/ Construct a circular vector by repeatedly applying the monadic generator
-- function to a seed. The generator function yields Just the next element
-- and the new seed or Nothing if there are no more elements.
--
-- This variant of 'unfoldrM' guarantees the resulting vector is non-
-- empty by supplying an initial element @a@.
--
--   @since 0.1.2
unfoldr1M
    :: (Monad m, G.Vector v a)
    => (b -> m (Maybe (a, b)))
    -> a
    -> b
    -> m (CircularVector v a)
unfoldr1M :: (b -> m (Maybe (a, b))) -> a -> b -> m (CircularVector v a)
unfoldr1M b -> m (Maybe (a, b))
f a
a b
b = (v a -> CircularVector v a) -> m (v a) -> m (CircularVector v a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> CircularVector v a -> CircularVector v a
forall (v :: * -> *) a.
Vector v a =>
a -> CircularVector v a -> CircularVector v a
cons a
a (CircularVector v a -> CircularVector v a)
-> (v a -> CircularVector v a) -> v a -> CircularVector v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector) ((b -> m (Maybe (a, b))) -> b -> m (v a)
forall (m :: * -> *) (v :: * -> *) a b.
(Monad m, Vector v a) =>
(b -> m (Maybe (a, b))) -> b -> m (v a)
G.unfoldrM b -> m (Maybe (a, b))
f b
b)

-- | /O(n)/ Construct a circular vector by repeatedly applying the monadic generator
-- function to a seed. The generator function yields Just the next element and
-- the new seed or Nothing if there are no more elements.
--
-- If an unfold does not create meaningful values, 'Nothing' is
-- returned. Otherwise, 'Just' containing a circular vector is returned.
--
--   @since 0.1.2
unfoldrNM
    :: (Monad m, G.Vector v a)
    => Int
    -> (b -> m (Maybe (a, b)))
    -> b
    -> m (Maybe (CircularVector v a))
unfoldrNM :: Int
-> (b -> m (Maybe (a, b))) -> b -> m (Maybe (CircularVector v a))
unfoldrNM Int
n b -> m (Maybe (a, b))
f b
b = (v a -> Maybe (CircularVector v a))
-> m (v a) -> m (Maybe (CircularVector v a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector (Int -> (b -> m (Maybe (a, b))) -> b -> m (v a)
forall (m :: * -> *) (v :: * -> *) a b.
(Monad m, Vector v a) =>
Int -> (b -> m (Maybe (a, b))) -> b -> m (v a)
G.unfoldrNM Int
n b -> m (Maybe (a, b))
f b
b)

-- | /O(n)/ Construct a circular vector by repeatedly applying the monadic generator
-- function to a seed. The generator function yields Just the next element and
-- the new seed or Nothing if there are no more elements.
--
-- This variant of 'unfoldrNM' guarantees the resulting vector is non-
-- empty by supplying an initial element @a@.
--
--   @since 0.1.2
unfoldr1NM
    :: (Monad m, G.Vector v a)
    => Int
    -> (b -> m (Maybe (a, b)))
    -> a
    -> b
    -> m (CircularVector v a)
unfoldr1NM :: Int -> (b -> m (Maybe (a, b))) -> a -> b -> m (CircularVector v a)
unfoldr1NM Int
n b -> m (Maybe (a, b))
f a
a b
b = (v a -> CircularVector v a) -> m (v a) -> m (CircularVector v a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> CircularVector v a -> CircularVector v a
forall (v :: * -> *) a.
Vector v a =>
a -> CircularVector v a -> CircularVector v a
cons a
a (CircularVector v a -> CircularVector v a)
-> (v a -> CircularVector v a) -> v a -> CircularVector v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector) (Int -> (b -> m (Maybe (a, b))) -> b -> m (v a)
forall (m :: * -> *) (v :: * -> *) a b.
(Monad m, Vector v a) =>
Int -> (b -> m (Maybe (a, b))) -> b -> m (v a)
G.unfoldrNM Int
n b -> m (Maybe (a, b))
f b
b)

-- | /O(n)/ Construct a circular vector with n elements by repeatedly applying the
-- generator function to the already constructed part of the vector.
--
-- If 'constructN' does not create meaningful values, 'Nothing' is
-- returned. Otherwise, 'Just' containing a circular vector is returned.
--
--   @since 0.1.2
constructN :: G.Vector v a => Int -> (v a -> a) -> Maybe (CircularVector v a)
constructN :: Int -> (v a -> a) -> Maybe (CircularVector v a)
constructN Int
n v a -> a
f = v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector (Int -> (v a -> a) -> v a
forall (v :: * -> *) a. Vector v a => Int -> (v a -> a) -> v a
G.constructN Int
n v a -> a
f)

-- | /O(n)/ Construct a circular vector with n elements from right to left by repeatedly
-- applying the generator function to the already constructed part of the vector.
--
-- If 'constructrN' does not create meaningful values, 'Nothing' is
-- returned. Otherwise, 'Just' containing a circular vector is returned.
--
--   @since 0.1.2
constructrN :: G.Vector v a => Int -> (v a -> a) -> Maybe (CircularVector v a)
constructrN :: Int -> (v a -> a) -> Maybe (CircularVector v a)
constructrN Int
n v a -> a
f = v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector (Int -> (v a -> a) -> v a
forall (v :: * -> *) a. Vector v a => Int -> (v a -> a) -> v a
G.constructrN Int
n v a -> a
f)

-- | /O(n)/ Yield a circular vector of the given length containing the
-- values x, x+1 etc. This operation is usually more efficient than
-- 'enumFromTo'.
--
-- If an enumeration does not use meaningful indices, 'Nothing' is returned,
-- otherwise, 'Just' containing a circular vector.
--
--   @since 0.1.2
enumFromN :: (G.Vector v a, Num a) => a -> Int -> Maybe (CircularVector v a)
enumFromN :: a -> Int -> Maybe (CircularVector v a)
enumFromN a
a Int
n = v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector (a -> Int -> v a
forall (v :: * -> *) a. (Vector v a, Num a) => a -> Int -> v a
G.enumFromN a
a Int
n)

-- | /O(n)/ Yield a circular vector of length @max n 1@ containing the
-- values x, x+1 etc. This operation is usually more efficient than
-- 'enumFromTo'.
--
--   @since 0.1.2
enumFromN1 :: (G.Vector v a, Num a) => a -> Int -> CircularVector v a
enumFromN1 :: a -> Int -> CircularVector v a
enumFromN1 a
a Int
n = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (a -> Int -> v a
forall (v :: * -> *) a. (Vector v a, Num a) => a -> Int -> v a
G.enumFromN a
a (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
n Int
1))

-- | /O(n)/ Yield a circular vector of the given length containing the
-- values x, x+y, x+y+y etc. This operations is usually more efficient than
-- 'enumFromThenTo'.
--
-- If an enumeration does not use meaningful indices, 'Nothing' is returned,
-- otherwise, 'Just' containing a circular vector.
--
--   @since 0.1.2
enumFromStepN :: (G.Vector v a, Num a) => a -> a -> Int -> Maybe (CircularVector v a)
enumFromStepN :: a -> a -> Int -> Maybe (CircularVector v a)
enumFromStepN a
a0 a
a1 Int
n = v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector (a -> a -> Int -> v a
forall (v :: * -> *) a. (Vector v a, Num a) => a -> a -> Int -> v a
G.enumFromStepN a
a0 a
a1 Int
n)

-- | /O(n)/ Yield a circular vector of length @max n 1@ containing the
-- values x, x+y, x+y+y etc. This operations is usually more efficient than
-- 'enumFromThenTo'.
--
--   @since 0.1.2
enumFromStepN1 :: (G.Vector v a, Num a) => a -> a -> Int -> CircularVector v a
enumFromStepN1 :: a -> a -> Int -> CircularVector v a
enumFromStepN1 a
a0 a
a1 Int
n = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (a -> a -> Int -> v a
forall (v :: * -> *) a. (Vector v a, Num a) => a -> a -> Int -> v a
G.enumFromStepN a
a0 a
a1 (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
n Int
1))

-- | /O(n)/ Enumerate values from x to y.
--
-- If an enumeration does not use meaningful indices, 'Nothing' is returned,
-- otherwise, 'Just' containing a circular vector.
--
-- /WARNING/: This operation can be very inefficient. If at all possible,
-- use 'enumFromN' instead.
--
--
--   @since 0.1.2
enumFromTo :: (G.Vector v a, Enum a) => a -> a -> Maybe (CircularVector v a)
enumFromTo :: a -> a -> Maybe (CircularVector v a)
enumFromTo a
a0 a
a1 = v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector (a -> a -> v a
forall (v :: * -> *) a. (Vector v a, Enum a) => a -> a -> v a
G.enumFromTo a
a0 a
a1)

-- | /O(n)/ Enumerate values from x to y with a specific step z.
--
-- If an enumeration does not use meaningful indices, 'Nothing' is returned,
-- otherwise, 'Just' containing a circular vector.
--
-- /WARNING/: This operation can be very inefficient. If at all possible,
-- use 'enumFromStepN' instead.
--
--   @since 0.1.2
enumFromThenTo :: (G.Vector v a, Enum a) => a -> a -> a -> Maybe (CircularVector v a)
enumFromThenTo :: a -> a -> a -> Maybe (CircularVector v a)
enumFromThenTo a
a0 a
a1 a
a2 = v a -> Maybe (CircularVector v a)
forall (v :: * -> *) a.
Vector v a =>
v a -> Maybe (CircularVector v a)
fromVector (a -> a -> a -> v a
forall (v :: * -> *) a. (Vector v a, Enum a) => a -> a -> a -> v a
G.enumFromThenTo a
a0 a
a1 a
a2)

-- | /O(n)/ Prepend an element
--
--   @since 0.1.2
--
-- >>> cons 1 (unsafeFromList @Vector [2,3])
-- CircularVector {vector = [1,2,3], rotation = 0}
--
cons :: G.Vector v a => a -> CircularVector v a -> CircularVector v a
cons :: a -> CircularVector v a -> CircularVector v a
cons a
a CircularVector v a
cv = a -> v a -> CircularVector v a
forall (v :: * -> *) a.
Vector v a =>
a -> v a -> CircularVector v a
consV a
a (CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v a
cv)
{-# INLINE cons #-}

-- | /O(n)/ Prepend an element to a Vector
--
--   @since 0.1.2
--
-- >>> consV 1 (Data.Vector.fromList [2,3])
-- CircularVector {vector = [1,2,3], rotation = 0}
--
consV :: G.Vector v a => a -> v a -> CircularVector v a
consV :: a -> v a -> CircularVector v a
consV a
a = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v a -> CircularVector v a)
-> (v a -> v a) -> v a -> CircularVector v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> v a -> v a
forall (v :: * -> *) a. Vector v a => a -> v a -> v a
G.cons a
a
{-# INLINE consV #-}

-- | /O(n)/ Append an element
--
--   @since 0.1.2
--
-- >>> snoc (unsafeFromList @Vector [1,2]) 3
-- CircularVector {vector = [1,2,3], rotation = 0}
--
snoc :: G.Vector v a => CircularVector v a -> a -> CircularVector v a
snoc :: CircularVector v a -> a -> CircularVector v a
snoc = v a -> a -> CircularVector v a
forall (v :: * -> *) a.
Vector v a =>
v a -> a -> CircularVector v a
snocV (v a -> a -> CircularVector v a)
-> (CircularVector v a -> v a)
-> CircularVector v a
-> a
-> CircularVector v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Append an element to a Vector
--
--   @since 0.1.2
--
-- >>> snocV (Data.Vector.fromList [1,2]) 3
-- CircularVector {vector = [1,2,3], rotation = 0}
--
snocV :: G.Vector v a => v a -> a -> CircularVector v a
snocV :: v a -> a -> CircularVector v a
snocV v a
as = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v a -> CircularVector v a)
-> (a -> v a) -> a -> CircularVector v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v a -> a -> v a
forall (v :: * -> *) a. Vector v a => v a -> a -> v a
G.snoc v a
as

-- | /O(m+n)/ Concatenate two circular vectors
--
--   @since 0.1.2
--
-- >>> (unsafeFromList @Vector [1..3]) ++ (unsafeFromList [4..6])
-- CircularVector {vector = [1,2,3,4,5,6], rotation = 0}
--
(++) :: G.Vector v a => CircularVector v a -> CircularVector v a -> CircularVector v a
CircularVector v a
v ++ :: CircularVector v a -> CircularVector v a -> CircularVector v a
++ CircularVector v a
v' = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v a
v v a -> v a -> v a
forall (v :: * -> *) a. Vector v a => v a -> v a -> v a
G.++ CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v a
v')

-- | /O(n)/ Concatenate all circular vectors in the list
--
-- If list is empty, 'Nothing' is returned, otherwise 'Just'
-- containing the concatenated circular vectors
--
--   @since 0.1.2
--
-- >>> concat [(unsafeFromList @Vector [1..3]), (unsafeFromList [4..6])]
-- Just (CircularVector {vector = [1,2,3,4,5,6], rotation = 0})
--
concat :: G.Vector v a => [CircularVector v a] -> Maybe (CircularVector v a)
concat :: [CircularVector v a] -> Maybe (CircularVector v a)
concat [] = Maybe (CircularVector v a)
forall a. Maybe a
Nothing
concat (CircularVector v a
a:[CircularVector v a]
as) = CircularVector v a -> Maybe (CircularVector v a)
forall a. a -> Maybe a
Just (NonEmpty (CircularVector v a) -> CircularVector v a
forall (v :: * -> *) a.
Vector v a =>
NonEmpty (CircularVector v a) -> CircularVector v a
concat1 (CircularVector v a
a CircularVector v a
-> [CircularVector v a] -> NonEmpty (CircularVector v a)
forall a. a -> [a] -> NonEmpty a
:| [CircularVector v a]
as))
{-# INLINE concat #-}

-- | O(n) Concatenate all circular vectors in a non-empty list.
--
--   @since 0.1.2
--
-- >>> concat1 ((unsafeFromList @Vector [1..3]) :| [(unsafeFromList [4..6])])
-- CircularVector {vector = [1,2,3,4,5,6], rotation = 0}
--
concat1 :: G.Vector v a => NonEmpty (CircularVector v a) -> CircularVector v a
concat1 :: NonEmpty (CircularVector v a) -> CircularVector v a
concat1 = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v a -> CircularVector v a)
-> (NonEmpty (CircularVector v a) -> v a)
-> NonEmpty (CircularVector v a)
-> CircularVector v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (v a) -> v a
forall (v :: * -> *) a. Vector v a => NonEmpty (v a) -> v a
G.concatNE (NonEmpty (v a) -> v a)
-> (NonEmpty (CircularVector v a) -> NonEmpty (v a))
-> NonEmpty (CircularVector v a)
-> v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CircularVector v a -> v a)
-> NonEmpty (CircularVector v a) -> NonEmpty (v a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Map a function over a circular vector.
--
--   @since 0.1.2
--
-- >>> map (+1) $ unsafeFromList @Vector [1..3]
-- CircularVector {vector = [2,3,4], rotation = 0}
--
map :: (G.Vector v a, G.Vector v b) => (a -> b) -> CircularVector v a -> CircularVector v b
map :: (a -> b) -> CircularVector v a -> CircularVector v b
map a -> b
f (CircularVector v a
v Int
rot) = v b -> Int -> CircularVector v b
forall (v :: * -> *) a. v a -> Int -> CircularVector v a
CircularVector ((a -> b) -> v a -> v b
forall (v :: * -> *) a b.
(Vector v a, Vector v b) =>
(a -> b) -> v a -> v b
G.map a -> b
f v a
v) Int
rot

-- | /O(n)/ Apply a function to every element of a circular vector and
-- its index.
--
--   @since 0.1.2
--
-- >>> imap (\i a -> if i == 2 then a+1 else a+0) $ unsafeFromList @Vector [1..3]
-- CircularVector {vector = [1,2,4], rotation = 0}
--
imap :: (G.Vector v a, G.Vector v b) => (Int -> a -> b) -> CircularVector v a -> CircularVector v b
imap :: (Int -> a -> b) -> CircularVector v a -> CircularVector v b
imap Int -> a -> b
f = v b -> CircularVector v b
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v b -> CircularVector v b)
-> (CircularVector v a -> v b)
-> CircularVector v a
-> CircularVector v b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> a -> b) -> v a -> v b
forall (v :: * -> *) a b.
(Vector v a, Vector v b) =>
(Int -> a -> b) -> v a -> v b
G.imap Int -> a -> b
f (v a -> v b)
-> (CircularVector v a -> v a) -> CircularVector v a -> v b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | Map a function over a circular vector and concatenate the results.
--
--   @since 0.1.2
--
-- >>> concatMap (\a -> unsafeFromList @Vector [a,a]) (unsafeFromList [1,2,3])
-- CircularVector {vector = [1,1,2,2,3,3], rotation = 0}
--
concatMap
    :: (G.Vector v a, G.Vector v b)
    => (a -> CircularVector v b)
    -> CircularVector v a
    -> CircularVector v b
concatMap :: (a -> CircularVector v b)
-> CircularVector v a -> CircularVector v b
concatMap a -> CircularVector v b
f = v b -> CircularVector v b
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v b -> CircularVector v b)
-> (CircularVector v a -> v b)
-> CircularVector v a
-> CircularVector v b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> v b) -> v a -> v b
forall (v :: * -> *) a b.
(Vector v a, Vector v b) =>
(a -> v b) -> v a -> v b
G.concatMap (CircularVector v b -> v b
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector (CircularVector v b -> v b)
-> (a -> CircularVector v b) -> a -> v b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> CircularVector v b
f) (v a -> v b)
-> (CircularVector v a -> v a) -> CircularVector v a -> v b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Apply the monadic action to all elements of the circular
-- vector, yielding circular vector of results.
--
--   @since 0.1.2
--
-- >>> mapM Just (unsafeFromList @Vector [1..3])
-- Just (CircularVector {vector = [1,2,3], rotation = 0})
--
-- >>> mapM (const Nothing) (unsafeFromList @Vector [1..3])
-- Nothing
--
mapM :: (Monad m, G.Vector v a, G.Vector v b) => (a -> m b) -> CircularVector v a -> m (CircularVector v b)
mapM :: (a -> m b) -> CircularVector v a -> m (CircularVector v b)
mapM a -> m b
f = (v b -> CircularVector v b) -> m (v b) -> m (CircularVector v b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap v b -> CircularVector v b
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (m (v b) -> m (CircularVector v b))
-> (CircularVector v a -> m (v b))
-> CircularVector v a
-> m (CircularVector v b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> m b) -> v a -> m (v b)
forall (m :: * -> *) (v :: * -> *) a b.
(Monad m, Vector v a, Vector v b) =>
(a -> m b) -> v a -> m (v b)
G.mapM a -> m b
f (v a -> m (v b))
-> (CircularVector v a -> v a) -> CircularVector v a -> m (v b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Apply the monadic action to every element of a circular
-- vector and its index, yielding a circular vector of results.
--
--   @since 0.1.2
--
-- >>> imapM (\i a -> if i == 1 then Just a else Just 0) (unsafeFromList @Vector [1..3])
-- Just (CircularVector {vector = [0,2,0], rotation = 0})
--
-- >>> imapM (\_ _ -> Nothing) (unsafeFromList @Vector [1..3])
-- Nothing
--
imapM
    :: (Monad m, G.Vector v a, G.Vector v b)
    => (Int -> a -> m b)
    -> CircularVector v a
    -> m (CircularVector v b)
imapM :: (Int -> a -> m b) -> CircularVector v a -> m (CircularVector v b)
imapM Int -> a -> m b
f = (v b -> CircularVector v b) -> m (v b) -> m (CircularVector v b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap v b -> CircularVector v b
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (m (v b) -> m (CircularVector v b))
-> (CircularVector v a -> m (v b))
-> CircularVector v a
-> m (CircularVector v b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> a -> m b) -> v a -> m (v b)
forall (m :: * -> *) (v :: * -> *) a b.
(Monad m, Vector v a, Vector v b) =>
(Int -> a -> m b) -> v a -> m (v b)
G.imapM Int -> a -> m b
f (v a -> m (v b))
-> (CircularVector v a -> v a) -> CircularVector v a -> m (v b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Apply the monadic action to all elements of a circular vector
-- and ignore the results.
--
--   @since 0.1.2
--
-- >>> mapM_ (const $ Just ()) (unsafeFromList @Vector [1..3])
-- Just ()
--
-- >>> mapM_ (const Nothing) (unsafeFromList @Vector [1..3])
-- Nothing
--
mapM_ :: (Monad m, G.Vector v a, G.Vector v b) => (a -> m b) -> CircularVector v a -> m ()
mapM_ :: (a -> m b) -> CircularVector v a -> m ()
mapM_ a -> m b
f = (a -> m b) -> v a -> m ()
forall (m :: * -> *) (v :: * -> *) a b.
(Monad m, Vector v a) =>
(a -> m b) -> v a -> m ()
G.mapM_ a -> m b
f (v a -> m ())
-> (CircularVector v a -> v a) -> CircularVector v a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Apply the monadic action to every element of a circular
-- vector and its index, ignoring the results
--
--   @since 0.1.2
--
-- >>> imapM_ (\i a -> if i == 1 then print a else putStrLn "0") (unsafeFromList @Vector [1..3])
-- 0
-- 2
-- 0
--
-- >>> imapM_ (\_ _ -> Nothing) (unsafeFromList @Vector [1..3])
-- Nothing
--
imapM_ :: (Monad m, G.Vector v a) => (Int -> a -> m b) -> CircularVector v a -> m ()
imapM_ :: (Int -> a -> m b) -> CircularVector v a -> m ()
imapM_ Int -> a -> m b
f = (Int -> a -> m b) -> v a -> m ()
forall (m :: * -> *) (v :: * -> *) a b.
(Monad m, Vector v a) =>
(Int -> a -> m b) -> v a -> m ()
G.imapM_ Int -> a -> m b
f (v a -> m ())
-> (CircularVector v a -> v a) -> CircularVector v a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Apply the monadic action to all elements of the circular
-- vector, yielding a circular vector of results.
--
-- Equivalent to @flip 'mapM'@.
--
--   @since 0.1.2
forM :: (Monad m, G.Vector v a, G.Vector v b) => CircularVector v a -> (a -> m b) -> m (CircularVector v b)
forM :: CircularVector v a -> (a -> m b) -> m (CircularVector v b)
forM CircularVector v a
cv a -> m b
f = v b -> CircularVector v b
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v b -> CircularVector v b) -> m (v b) -> m (CircularVector v b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> v a -> (a -> m b) -> m (v b)
forall (m :: * -> *) (v :: * -> *) a b.
(Monad m, Vector v a, Vector v b) =>
v a -> (a -> m b) -> m (v b)
G.forM (CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v a
cv) a -> m b
f

-- | /O(n)/ Apply the monadic action to all elements of a circular
-- vector and ignore the results.
--
-- Equivalent to @flip 'mapM_'@.
--
--   @since 0.1.2
forM_ :: (Monad m, G.Vector v a) => CircularVector v a -> (a -> m b) -> m ()
forM_ :: CircularVector v a -> (a -> m b) -> m ()
forM_ CircularVector v a
cv a -> m b
f = v a -> (a -> m b) -> m ()
forall (m :: * -> *) (v :: * -> *) a b.
(Monad m, Vector v a) =>
v a -> (a -> m b) -> m ()
G.forM_ (CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v a
cv) a -> m b
f

-- | /O(n)/ Drop repeated adjacent elements.
--
-- >>> toList $ uniq $ unsafeFromList @Vector [1,1,2,2,3,3,1]
-- [1,2,3]
--
-- >>> toList $ uniq $ unsafeFromList @Vector [1,2,3,1]
-- [1,2,3]
uniq :: (G.Vector v a, Eq a) => CircularVector v a -> CircularVector v a
uniq :: CircularVector v a -> CircularVector v a
uniq = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v a -> CircularVector v a)
-> (CircularVector v a -> v a)
-> CircularVector v a
-> CircularVector v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v a -> v a
forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> v a
trim (v a -> v a)
-> (CircularVector v a -> v a) -> CircularVector v a -> v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v a -> v a
forall (v :: * -> *) a. (Vector v a, Eq a) => v a -> v a
G.uniq (v a -> v a)
-> (CircularVector v a -> v a) -> CircularVector v a -> v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector
  where
    trim :: v a -> v a
trim v a
v
      | v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
G.length v a
v Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 Bool -> Bool -> Bool
|| v a -> a
forall (v :: * -> *) a. Vector v a => v a -> a
G.head v a
v a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= v a -> a
forall (v :: * -> *) a. Vector v a => v a -> a
G.last v a
v
        = v a
v
      | Bool
otherwise
        = v a -> v a
trim (v a -> v a
forall (v :: * -> *) a. Vector v a => v a -> v a
G.unsafeInit v a
v)

-- | /O(n)/ Drop elements when predicate returns Nothing
--
-- If no elements satisfy the predicate, the resulting vector may be empty.
--
--   @since 0.1.2
--
-- >>> mapMaybe (\a -> if a == 2 then Nothing else Just a) (unsafeFromList @Vector [1..3])
-- [1,3]
mapMaybe
    :: (G.Vector v a, G.Vector v b)
    => (a -> Maybe b)
    -> CircularVector v a
    -> v b
mapMaybe :: (a -> Maybe b) -> CircularVector v a -> v b
mapMaybe a -> Maybe b
f = (a -> Maybe b) -> v a -> v b
forall (v :: * -> *) a b.
(Vector v a, Vector v b) =>
(a -> Maybe b) -> v a -> v b
G.mapMaybe a -> Maybe b
f (v a -> v b)
-> (CircularVector v a -> v a) -> CircularVector v a -> v b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Drop elements when predicate, applied to index and value, returns Nothing
--
-- If no elements satisfy the predicate, the resulting vector may be empty.
--
--   @since 0.1.2
--
-- >>> imapMaybe (\i a -> if a == 2 || i == 2 then Nothing else Just a) (unsafeFromList @Vector [1..3])
-- [1]
--
imapMaybe
    :: (G.Vector v a, G.Vector v b)
    => (Int -> a -> Maybe b)
    -> CircularVector v a
    -> v b
imapMaybe :: (Int -> a -> Maybe b) -> CircularVector v a -> v b
imapMaybe Int -> a -> Maybe b
f = (Int -> a -> Maybe b) -> v a -> v b
forall (v :: * -> *) a b.
(Vector v a, Vector v b) =>
(Int -> a -> Maybe b) -> v a -> v b
G.imapMaybe Int -> a -> Maybe b
f (v a -> v b)
-> (CircularVector v a -> v a) -> CircularVector v a -> v b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Yield the longest prefix of elements satisfying the predicate
-- without copying.
--
-- If no elements satisfy the predicate, the resulting vector may be empty.
--
--   @since 0.1.2
--
-- >>> takeWhile (/= 3) (unsafeFromList @Vector [1..3])
-- [1,2]
--
takeWhile :: G.Vector v a => (a -> Bool) -> CircularVector v a -> v a
takeWhile :: (a -> Bool) -> CircularVector v a -> v a
takeWhile a -> Bool
f = (a -> Bool) -> v a -> v a
forall (v :: * -> *) a. Vector v a => (a -> Bool) -> v a -> v a
G.takeWhile a -> Bool
f (v a -> v a)
-> (CircularVector v a -> v a) -> CircularVector v a -> v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Drop the longest prefix of elements that satisfy the predicate
-- without copying.
--
-- If all elements satisfy the predicate, the resulting vector may be empty.
--
--   @since 0.1.2
--
-- >>> dropWhile (/= 3) (unsafeFromList @Vector [1..3])
-- [3]
--
dropWhile :: G.Vector v a => (a -> Bool) -> CircularVector v a -> v a
dropWhile :: (a -> Bool) -> CircularVector v a -> v a
dropWhile a -> Bool
f = (a -> Bool) -> v a -> v a
forall (v :: * -> *) a. Vector v a => (a -> Bool) -> v a -> v a
G.dropWhile a -> Bool
f (v a -> v a)
-> (CircularVector v a -> v a) -> CircularVector v a -> v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Split the circular vector in two parts, the first one
-- containing those elements that satisfy the predicate and the second
-- one those that don't. The relative order of the elements is preserved
-- at the cost of a sometimes reduced performance compared to
-- 'unstablePartition'.
--
-- If all or no elements satisfy the predicate, one of the resulting vectors
-- may be empty.
--
--   @since 0.1.2
--
-- >>> partition (< 3) (unsafeFromList @Vector [1..5])
-- ([1,2],[3,4,5])
--
partition :: G.Vector v a => (a -> Bool) -> CircularVector v a -> (v a, v a)
partition :: (a -> Bool) -> CircularVector v a -> (v a, v a)
partition a -> Bool
f = (a -> Bool) -> v a -> (v a, v a)
forall (v :: * -> *) a.
Vector v a =>
(a -> Bool) -> v a -> (v a, v a)
G.partition a -> Bool
f (v a -> (v a, v a))
-> (CircularVector v a -> v a) -> CircularVector v a -> (v a, v a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Split the circular vector in two parts, the first one
-- containing those elements that satisfy the predicate and the second
-- one those that don't. The order of the elements is not preserved but
-- the operation is often faster than 'partition'.
--
-- If all or no elements satisfy the predicate, one of the resulting vectors
-- may be empty.
--
--   @since 0.1.2
unstablePartition
    :: G.Vector v a
    => (a -> Bool)
    -> CircularVector v a
    -> (v a, v a)
unstablePartition :: (a -> Bool) -> CircularVector v a -> (v a, v a)
unstablePartition a -> Bool
f = (a -> Bool) -> v a -> (v a, v a)
forall (v :: * -> *) a.
Vector v a =>
(a -> Bool) -> v a -> (v a, v a)
G.unstablePartition a -> Bool
f (v a -> (v a, v a))
-> (CircularVector v a -> v a) -> CircularVector v a -> (v a, v a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Split the circular vector into the longest prefix of elements
-- that satisfy the predicate and the rest without copying.
--
-- If all or no elements satisfy the predicate, one of the resulting vectors
-- may be empty.
--
--   @since 0.1.2
--
-- >>> span (== 1) (unsafeFromList @Vector [1,1,2,3,1])
-- ([1,1],[2,3,1])
--
span :: G.Vector v a => (a -> Bool) -> CircularVector v a -> (v a, v a)
span :: (a -> Bool) -> CircularVector v a -> (v a, v a)
span a -> Bool
f = (a -> Bool) -> v a -> (v a, v a)
forall (v :: * -> *) a.
Vector v a =>
(a -> Bool) -> v a -> (v a, v a)
G.span a -> Bool
f (v a -> (v a, v a))
-> (CircularVector v a -> v a) -> CircularVector v a -> (v a, v a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Split the circular vector into the longest prefix of elements that do not
-- satisfy the predicate and the rest without copying.
--
-- If all or no elements satisfy the predicate, one of the resulting vectors
-- may be empty.
--
--   @since 0.1.2
--
-- >>> break (== 2) (unsafeFromList @Vector [1,1,2,3,1])
-- ([1,1],[2,3,1])
--
break :: G.Vector v a => (a -> Bool) -> CircularVector v a -> (v a, v a)
break :: (a -> Bool) -> CircularVector v a -> (v a, v a)
break a -> Bool
f = (a -> Bool) -> v a -> (v a, v a)
forall (v :: * -> *) a.
Vector v a =>
(a -> Bool) -> v a -> (v a, v a)
G.break a -> Bool
f (v a -> (v a, v a))
-> (CircularVector v a -> v a) -> CircularVector v a -> (v a, v a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Check if the circular vector contains an element
--
--   @since 0.1.2
--
-- >>> elem 1 $ unsafeFromList @Vector [1..3]
-- True
-- >>> elem 4 $ unsafeFromList @Vector [1..3]
-- False
--
elem :: (G.Vector v a, Eq a) => a -> CircularVector v a -> Bool
elem :: a -> CircularVector v a -> Bool
elem a
a = a -> v a -> Bool
forall (v :: * -> *) a. (Vector v a, Eq a) => a -> v a -> Bool
G.elem a
a (v a -> Bool)
-> (CircularVector v a -> v a) -> CircularVector v a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Check if the circular vector does not contain an element
-- (inverse of 'elem')
--
--   @since 0.1.2
--
-- >>> notElem 1 $ unsafeFromList @Vector [1..3]
-- False
--
-- >>> notElem 4 $ unsafeFromList @Vector [1..3]
-- True
--
notElem :: (G.Vector v a, Eq a) => a -> CircularVector v a -> Bool
notElem :: a -> CircularVector v a -> Bool
notElem a
a = a -> v a -> Bool
forall (v :: * -> *) a. (Vector v a, Eq a) => a -> v a -> Bool
G.notElem a
a (v a -> Bool)
-> (CircularVector v a -> v a) -> CircularVector v a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Yield 'Just' the first element matching the predicate or
-- 'Nothing' if no such element exists.
--
--   @since 0.1.2
--
-- >>> find (< 2) $ unsafeFromList @Vector [1..3]
-- Just 1
--
-- >>> find (< 0) $ unsafeFromList @Vector [1..3]
-- Nothing
--
find :: G.Vector v a => (a -> Bool) -> CircularVector v a -> Maybe a
find :: (a -> Bool) -> CircularVector v a -> Maybe a
find a -> Bool
f = (a -> Bool) -> v a -> Maybe a
forall (v :: * -> *) a. Vector v a => (a -> Bool) -> v a -> Maybe a
G.find a -> Bool
f (v a -> Maybe a)
-> (CircularVector v a -> v a) -> CircularVector v a -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Yield 'Just' the index of the first element matching the
-- predicate or 'Nothing' if no such element exists.
--
--   @since 0.1.2
--
-- >>> findIndex (< 2) $ unsafeFromList @Vector [1..3]
-- Just 0
--
-- >>> findIndex (< 0) $ unsafeFromList @Vector [1..3]
-- Nothing
--
-- >>> findIndex (==1) $ rotateRight 1 (unsafeFromList @Vector [1..3])
-- Just 2
findIndex :: G.Vector v a => (a -> Bool) -> CircularVector v a -> Maybe Int
findIndex :: (a -> Bool) -> CircularVector v a -> Maybe Int
findIndex a -> Bool
f = (a -> Bool) -> v a -> Maybe Int
forall (v :: * -> *) a.
Vector v a =>
(a -> Bool) -> v a -> Maybe Int
G.findIndex a -> Bool
f (v a -> Maybe Int)
-> (CircularVector v a -> v a) -> CircularVector v a -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Yield the indices of elements satisfying the predicate in
-- ascending order.
--
--   @since 0.1.2
--
-- >>> findIndices (< 3) $ unsafeFromList @Vector [1..3]
-- [0,1]
--
-- >>> findIndices (< 0) $ unsafeFromList @Vector [1..3]
-- []
--
findIndices :: (G.Vector v a, G.Vector v Int) => (a -> Bool) -> CircularVector v a -> v Int
findIndices :: (a -> Bool) -> CircularVector v a -> v Int
findIndices a -> Bool
f = (a -> Bool) -> v a -> v Int
forall (v :: * -> *) a.
(Vector v a, Vector v Int) =>
(a -> Bool) -> v a -> v Int
G.findIndices a -> Bool
f (v a -> v Int)
-> (CircularVector v a -> v a) -> CircularVector v a -> v Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Yield 'Just' the index of the first occurence of the given
-- element or 'Nothing' if the circular vector does not contain the
-- element. This is a specialised version of 'findIndex'.
--
--   @since 0.1.2
--
-- >>> elemIndex 1 $ unsafeFromList @Vector [1..3]
-- Just 0
--
-- >>> elemIndex 0 $ unsafeFromList @Vector [1..3]
-- Nothing
--
elemIndex :: (G.Vector v a, Eq a) => a -> CircularVector v a -> Maybe Int
elemIndex :: a -> CircularVector v a -> Maybe Int
elemIndex a
a = a -> v a -> Maybe Int
forall (v :: * -> *) a. (Vector v a, Eq a) => a -> v a -> Maybe Int
G.elemIndex a
a (v a -> Maybe Int)
-> (CircularVector v a -> v a) -> CircularVector v a -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Yield the indices of all occurences of the given element in
-- ascending order. This is a specialised version of 'findIndices'.
--
--   @since 0.1.2
--
-- >>> elemIndices 1 $ unsafeFromList @Vector [1,2,3,1]
-- [0,3]
--
-- >>> elemIndices 0 $ unsafeFromList @Vector [1..3]
-- []
--
elemIndices :: (G.Vector v a, G.Vector v Int, Eq a) => a -> CircularVector v a -> v Int
elemIndices :: a -> CircularVector v a -> v Int
elemIndices a
a = a -> v a -> v Int
forall (v :: * -> *) a.
(Vector v a, Vector v Int, Eq a) =>
a -> v a -> v Int
G.elemIndices a
a (v a -> v Int)
-> (CircularVector v a -> v a) -> CircularVector v a -> v Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Drop elements that do not satisfy the predicate.
--
-- If no elements satisfy the predicate, the resulting vector may be empty.
--
-- >>> filter (\a -> if a == 2 then False else True) (unsafeFromList @Vector [1..3])
-- [1,3]
--
-- >>> filter (const False) (unsafeFromList @Vector [1..3])
-- []
--
filter :: G.Vector v a => (a -> Bool) -> CircularVector v a -> v a
filter :: (a -> Bool) -> CircularVector v a -> v a
filter a -> Bool
f = (a -> Bool) -> v a -> v a
forall (v :: * -> *) a. Vector v a => (a -> Bool) -> v a -> v a
G.filter a -> Bool
f (v a -> v a)
-> (CircularVector v a -> v a) -> CircularVector v a -> v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector


-- | /O(n)/ Drop elements that do not satisfy the predicate which is
-- applied to values and their indices.
--
-- If no elements satisfy the predicate, the resulting vector may be empty.
--
--   @since 0.1.2
--
-- >>> ifilter (\i a -> if a == 2 || i == 0 then False else True) (unsafeFromList @Vector [1..3])
-- [3]
--
-- >>> ifilter (\_ _ -> False) (unsafeFromList @Vector [1..3])
-- []
--
ifilter
    :: G.Vector v a
    => (Int -> a -> Bool)
    -> CircularVector v a
    -> v a
ifilter :: (Int -> a -> Bool) -> CircularVector v a -> v a
ifilter Int -> a -> Bool
f = (Int -> a -> Bool) -> v a -> v a
forall (v :: * -> *) a.
Vector v a =>
(Int -> a -> Bool) -> v a -> v a
G.ifilter Int -> a -> Bool
f (v a -> v a)
-> (CircularVector v a -> v a) -> CircularVector v a -> v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- | /O(n)/ Drop elements that do not satisfy the monadic predicate.
--
-- If no elements satisfy the predicate, the resulting vector may be empty.
--
--   @since 0.1.2
--
-- >>> filterM (\a -> if a == 2 then Just False else Just True) (unsafeFromList @Vector [1..3])
-- Just [1,3]
--
-- >>> filterM (\a -> if a == 2 then Nothing else Just True) (unsafeFromList @Vector [1..3])
-- Nothing
--
-- >>> filterM (const $ Just False) (unsafeFromList @Vector [1..3])
-- Just []
--
filterM
    :: (Monad m, G.Vector v a)
    => (a -> m Bool)
    -> CircularVector v a
    -> m (v a)
filterM :: (a -> m Bool) -> CircularVector v a -> m (v a)
filterM a -> m Bool
f = (a -> m Bool) -> v a -> m (v a)
forall (m :: * -> *) (v :: * -> *) a.
(Monad m, Vector v a) =>
(a -> m Bool) -> v a -> m (v a)
G.filterM a -> m Bool
f (v a -> m (v a))
-> (CircularVector v a -> v a) -> CircularVector v a -> m (v a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector

-- -- | /O(n)/ Drop elements that do not satisfy the monadic predicate that is
-- -- a function of index and value.
-- --
-- -- If no elements satisfy the predicate, the resulting vector may be empty.
-- --
-- --   @since 0.1.2
-- --
-- -- >>> ifilterM (\i a -> if a == 2 || i == 0 then Just False else Just True) (unsafeFromList @Vector [1..3])
-- -- Just [3]
-- --
-- -- >>> ifilterM (\i a -> if a == 2 || i == 0 then Nothing else Just True) (unsafeFromList @Vector [1..3])
-- -- Nothing
-- --
-- -- >>> ifilterM (\_ _ -> Just False) (unsafeFromList @Vector [1..3])
-- -- Just []
-- --
-- ifilterM
--     :: (Monad m, G.Vector v a)
--     => (Int -> a -> m Bool)
--     -> CircularVector v a
--     -> m (Vector a)
-- ifilterM f = G.ifilterM f . toVector

-- | /O(n)/ Yield the circular vector obtained by replacing each element
-- @i@ of the circular index vector by @xs'!'i@. This is equivalent to
-- @'map' (xs'!') is@ but is often much more efficient.
--
--   @since 0.1.2
--
-- >>> toList $ backpermute @Vector (unsafeFromList @Vector [1..3]) (unsafeFromList @Vector [2,0])
-- [3,1]
--
backpermute :: (G.Vector v a, G.Vector v Int) =>
  CircularVector v a -> CircularVector v Int -> CircularVector v a
backpermute :: CircularVector v a -> CircularVector v Int -> CircularVector v a
backpermute CircularVector v a
v CircularVector v Int
i = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v a -> CircularVector v a) -> v a -> CircularVector v a
forall a b. (a -> b) -> a -> b
$ v a -> v Int -> v a
forall (v :: * -> *) a.
(Vector v a, Vector v Int) =>
v a -> v Int -> v a
G.backpermute (CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v a
v) (CircularVector v Int -> v Int
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v Int
i)

-- | Same as 'backpermute' but without bounds checking.
--
--   @since 0.1.2
unsafeBackpermute
    :: (G.Vector v a, G.Vector v Int)
    => CircularVector v a
    -> CircularVector v Int
    -> CircularVector v a
unsafeBackpermute :: CircularVector v a -> CircularVector v Int -> CircularVector v a
unsafeBackpermute CircularVector v a
v CircularVector v Int
i = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v a -> v Int -> v a
forall (v :: * -> *) a.
(Vector v a, Vector v Int) =>
v a -> v Int -> v a
G.unsafeBackpermute (CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v a
v) (CircularVector v Int -> v Int
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector CircularVector v Int
i))

-- | Apply a destructive operation to a circular vector. The operation
-- will be performed in place if it is safe to do so and will modify a
-- copy of the circular vector otherwise.
--
--   @since 0.1.2
modify
    :: G.Vector v a
    => (forall s. G.Mutable v s a -> ST s ())
    -> CircularVector v a
    -> CircularVector v a
modify :: (forall s. Mutable v s a -> ST s ())
-> CircularVector v a -> CircularVector v a
modify forall s. Mutable v s a -> ST s ()
p = v a -> CircularVector v a
forall (v :: * -> *) a. Vector v a => v a -> CircularVector v a
unsafeFromVector (v a -> CircularVector v a)
-> (CircularVector v a -> v a)
-> CircularVector v a
-> CircularVector v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall s. Mutable v s a -> ST s ()) -> v a -> v a
forall (v :: * -> *) a.
Vector v a =>
(forall s. Mutable v s a -> ST s ()) -> v a -> v a
G.modify forall s. Mutable v s a -> ST s ()
p (v a -> v a)
-> (CircularVector v a -> v a) -> CircularVector v a -> v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector v a -> v a
forall (v :: * -> *) a. Vector v a => CircularVector v a -> v a
toVector