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

module Data.Vector.Circular
  ( -- * 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.++)
  , concat
  , concat1
    -- ** Restricting memory usage
  , force

    -- ** Template Haskell
  , vec

    -- * Conversion
  , toVector
  , fromVector
  , 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
  , 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 Data.Primitive.MutVar ( newMutVar, readMutVar, writeMutVar )
import Data.Semigroup.Foldable.Class (Foldable1)
import Data.Monoid (All(..))
import Data.Vector (Vector)
import Data.Vector.NonEmpty (NonEmptyVector)
import Data.Functor.Classes
import Text.Read (readPrec)
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.Foldable as Foldable
import qualified Data.Semigroup.Foldable.Class as Foldable1
import qualified Data.Vector as Vector
import qualified Data.Vector.Mutable as MVector
import qualified Data.Vector.NonEmpty as NonEmpty
import qualified Prelude


-- | 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 a = CircularVector
  { CircularVector a -> NonEmptyVector a
vector :: {-# UNPACK #-} !(NonEmptyVector a)
  , CircularVector a -> Int
rotation :: {-# UNPACK #-} !Int
  }
  deriving stock
    ( Functor -- ^ @since 0.1
    , Generic -- ^ @since 0.1.1
    , Ord     -- ^ @since 0.1
    , Read    -- ^ @since 0.1
    , Show    -- ^ @since 0.1
    )
  deriving anyclass
    ( NFData -- ^ @since 0.1.1
    )

-- | @since 0.1.1
instance Traversable CircularVector where
  traverse :: (Applicative f) => (a -> f b) -> CircularVector a -> f (CircularVector b)
  traverse :: (a -> f b) -> CircularVector a -> f (CircularVector b)
traverse a -> f b
f (CircularVector NonEmptyVector a
v Int
rot) =
    NonEmptyVector b -> Int -> CircularVector b
forall a. NonEmptyVector a -> Int -> CircularVector a
CircularVector (NonEmptyVector b -> Int -> CircularVector b)
-> f (NonEmptyVector b) -> f (Int -> CircularVector b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> f b) -> NonEmptyVector a -> f (NonEmptyVector b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse a -> f b
f NonEmptyVector a
v f (Int -> CircularVector b) -> f Int -> f (CircularVector b)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> f Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
rot

-- | @since 0.1
instance Eq a => Eq (CircularVector a) where
  (==) :: CircularVector a -> CircularVector a -> Bool
  == :: CircularVector a -> CircularVector a -> Bool
(==) = (a -> a -> Bool) -> CircularVector a -> CircularVector a -> Bool
forall (f :: * -> *) a b.
Eq1 f =>
(a -> b -> Bool) -> f a -> f b -> Bool
liftEq a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(==)

-- | @since 0.1.2
instance Eq1 CircularVector where
  liftEq :: (a -> b -> Bool) -> CircularVector a -> CircularVector b -> Bool
  liftEq :: (a -> b -> Bool) -> CircularVector a -> CircularVector b -> Bool
liftEq a -> b -> Bool
eq c0 :: CircularVector a
c0@(CircularVector NonEmptyVector a
x Int
rx) c1 :: CircularVector b
c1@(CircularVector NonEmptyVector b
y Int
ry)
    | NonEmptyVector a -> Int
forall a. NonEmptyVector a -> Int
NonEmpty.length NonEmptyVector a
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= NonEmptyVector b -> Int
forall a. NonEmptyVector a -> Int
NonEmpty.length NonEmptyVector b
y = Bool
False
    | Int
rx Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ry = (a -> b -> Bool) -> NonEmptyVector a -> NonEmptyVector b -> Bool
forall (f :: * -> *) a b.
Eq1 f =>
(a -> b -> Bool) -> f a -> f b -> Bool
liftEq a -> b -> Bool
eq NonEmptyVector a
x NonEmptyVector b
y
    | Bool
otherwise = All -> Bool
getAll (All -> Bool) -> All -> Bool
forall a b. (a -> b) -> a -> b
$ ((Int -> All) -> [Int] -> All) -> [Int] -> (Int -> All) -> All
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Int -> All) -> [Int] -> All
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
Prelude.foldMap [Int
0..NonEmptyVector a -> Int
forall a. NonEmptyVector a -> Int
NonEmpty.length NonEmptyVector a
xInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1] ((Int -> All) -> All) -> (Int -> All) -> All
forall a b. (a -> b) -> a -> b
$ \Int
i ->
        Bool -> All
All (CircularVector a -> Int -> a
forall a. CircularVector a -> Int -> a
index CircularVector a
c0 Int
i a -> b -> Bool
`eq` CircularVector b -> Int -> b
forall a. CircularVector a -> Int -> a
index CircularVector b
c1 Int
i)

-- | @since 0.1.2
instance Ord1 CircularVector where
  liftCompare :: (a -> b -> Ordering) -> CircularVector a -> CircularVector b -> Ordering
  liftCompare :: (a -> b -> Ordering)
-> CircularVector a -> CircularVector b -> Ordering
liftCompare a -> b -> Ordering
cmp (CircularVector NonEmptyVector a
x Int
rx) (CircularVector NonEmptyVector b
y Int
ry)
    = (a -> b -> Ordering)
-> NonEmptyVector a -> NonEmptyVector b -> Ordering
forall (f :: * -> *) a b.
Ord1 f =>
(a -> b -> Ordering) -> f a -> f b -> Ordering
liftCompare a -> b -> Ordering
cmp NonEmptyVector a
x NonEmptyVector b
y Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
rx Int
ry

-- | @since 0.1.2
instance Show1 CircularVector where
  liftShowsPrec :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> CircularVector a -> ShowS
  liftShowsPrec :: (Int -> a -> ShowS)
-> ([a] -> ShowS) -> Int -> CircularVector a -> ShowS
liftShowsPrec Int -> a -> ShowS
sp [a] -> ShowS
sl Int
d (CircularVector NonEmptyVector a
x Int
rx) =
    (Int -> NonEmptyVector a -> ShowS)
-> (Int -> Int -> ShowS)
-> String
-> Int
-> NonEmptyVector a
-> Int
-> ShowS
forall a b.
(Int -> a -> ShowS)
-> (Int -> b -> ShowS) -> String -> Int -> a -> b -> ShowS
showsBinaryWith ((Int -> a -> ShowS)
-> ([a] -> ShowS) -> Int -> NonEmptyVector a -> ShowS
forall (f :: * -> *) a.
Show1 f =>
(Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> f a -> ShowS
liftShowsPrec Int -> a -> ShowS
sp [a] -> ShowS
sl) Int -> Int -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec String
"CircularVector" Int
d NonEmptyVector a
x Int
rx

-- | @since 0.1.2
instance Read1 CircularVector where
  liftReadPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec (CircularVector a)
liftReadPrec ReadPrec a
rp ReadPrec [a]
rl = ReadPrec (CircularVector a) -> ReadPrec (CircularVector a)
forall a. ReadPrec a -> ReadPrec a
readData (ReadPrec (CircularVector a) -> ReadPrec (CircularVector a))
-> ReadPrec (CircularVector a) -> ReadPrec (CircularVector a)
forall a b. (a -> b) -> a -> b
$
    ReadPrec (NonEmptyVector a)
-> ReadPrec Int
-> String
-> (NonEmptyVector a -> Int -> CircularVector a)
-> ReadPrec (CircularVector a)
forall a b t.
ReadPrec a -> ReadPrec b -> String -> (a -> b -> t) -> ReadPrec t
readBinaryWith (ReadPrec a -> ReadPrec [a] -> ReadPrec (NonEmptyVector a)
forall (f :: * -> *) a.
Read1 f =>
ReadPrec a -> ReadPrec [a] -> ReadPrec (f a)
liftReadPrec ReadPrec a
rp ReadPrec [a]
rl) ReadPrec Int
forall a. Read a => ReadPrec a
readPrec String
"CircularVector" NonEmptyVector a -> Int -> CircularVector a
forall a. NonEmptyVector a -> Int -> CircularVector a
CircularVector
  liftReadListPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec [CircularVector a]
liftReadListPrec = ReadPrec a -> ReadPrec [a] -> ReadPrec [CircularVector a]
forall (f :: * -> *) a.
Read1 f =>
ReadPrec a -> ReadPrec [a] -> ReadPrec [f a]
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
instance Semigroup (CircularVector a) where
  (<>) :: CircularVector a -> CircularVector a -> CircularVector a
  CircularVector a
lhs <> :: CircularVector a -> CircularVector a -> CircularVector a
<> CircularVector a
rhs = NonEmptyVector a -> Int -> CircularVector a
forall a. NonEmptyVector a -> Int -> CircularVector a
CircularVector NonEmptyVector a
v Int
0
    where
      szLhs :: Int
szLhs = CircularVector a -> Int
forall a. CircularVector a -> Int
length CircularVector a
lhs
      szRhs :: Int
szRhs = CircularVector a -> Int
forall a. CircularVector a -> Int
length CircularVector a
rhs
      sz :: Int
sz = Int
szLhs Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
szRhs
      v :: NonEmptyVector a
v = Vector a -> NonEmptyVector a
forall a. Vector a -> NonEmptyVector a
NonEmpty.unsafeFromVector
            (Vector a -> NonEmptyVector a) -> Vector a -> NonEmptyVector a
forall a b. (a -> b) -> a -> b
$ Int -> (Int -> a) -> Vector a
forall a. Int -> (Int -> a) -> Vector a
Vector.generate Int
sz
            ((Int -> a) -> Vector a) -> (Int -> a) -> Vector 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 a -> Int -> a
forall a. CircularVector a -> Int -> a
index CircularVector a
lhs Int
ix
                else CircularVector a -> Int -> a
forall a. CircularVector a -> Int -> a
index CircularVector a
rhs (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
szLhs)
  {-# inline (<>) #-}

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

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

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

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

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

-- | @since 0.1
instance Lift a => Lift (CircularVector a) where
  lift :: CircularVector a -> Q Exp
lift CircularVector a
c = do
    Exp
v <- [|NonEmpty.toVector (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` (Name -> Exp
VarE 'NonEmpty.unsafeFromVector Exp -> Exp -> Exp
`AppE` Exp
v)
      Exp -> Exp -> Exp
`AppE` Exp
r
#if MIN_VERSION_template_haskell(2,16,0)
  liftTyped :: CircularVector a -> Q (TExp (CircularVector a))
liftTyped = Q Exp -> Q (TExp (CircularVector a))
forall a. Q Exp -> Q (TExp a)
unsafeTExpCoerce (Q Exp -> Q (TExp (CircularVector a)))
-> (CircularVector a -> Q Exp)
-> CircularVector a
-> Q (TExp (CircularVector a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector 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
length :: CircularVector a -> Int
length :: CircularVector a -> Int
length (CircularVector NonEmptyVector a
v Int
_) = NonEmptyVector a -> Int
forall a. NonEmptyVector a -> Int
NonEmpty.length NonEmptyVector a
v
{-# inline length #-}

-- | Lazily-accumulating monoidal fold over a 'CircularVector'.
--   @since 0.1
foldMap :: Monoid m => (a -> m) -> CircularVector a -> m
foldMap :: (a -> m) -> CircularVector a -> m
foldMap a -> m
f = \CircularVector a
v ->
  let len :: Int
len = CircularVector a -> Int
forall a. CircularVector a -> Int
Data.Vector.Circular.length CircularVector 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 a -> Int -> a
forall a. CircularVector a -> Int -> a
index CircularVector 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
foldMap' :: Monoid m => (a -> m) -> CircularVector a -> m
foldMap' :: (a -> m) -> CircularVector a -> m
foldMap' a -> m
f = \CircularVector a
v ->
  let len :: Int
len = CircularVector a -> Int
forall a. CircularVector a -> Int
Data.Vector.Circular.length CircularVector 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 a -> Int -> a
forall a. CircularVector a -> Int -> a
index CircularVector a
v Int
ix))
        | Bool
otherwise = m
acc
  in Int -> m -> m
go Int
0 m
forall a. Monoid a => a
mempty
{-# inline foldMap' #-}

-- | @since 0.1
foldr :: (a -> b -> b) -> b -> CircularVector a -> b
foldr :: (a -> b -> b) -> b -> CircularVector a -> b
foldr = (a -> b -> b) -> b -> CircularVector a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
Foldable.foldr

-- | @since 0.1
foldl :: (b -> a -> b) -> b -> CircularVector a -> b
foldl :: (b -> a -> b) -> b -> CircularVector a -> b
foldl = (b -> a -> b) -> b -> CircularVector a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Foldable.foldl

-- | @since 0.1
foldr' :: (a -> b -> b) -> b -> CircularVector a -> b
foldr' :: (a -> b -> b) -> b -> CircularVector a -> b
foldr' = (a -> b -> b) -> b -> CircularVector a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
Foldable.foldr'

-- | @since 0.1
foldl' :: (b -> a -> b) -> b -> CircularVector a -> b
foldl' :: (b -> a -> b) -> b -> CircularVector a -> b
foldl' = (b -> a -> b) -> b -> CircularVector a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Foldable.foldl'

-- | @since 0.1
foldr1 :: (a -> a -> a) -> CircularVector a -> a
foldr1 :: (a -> a -> a) -> CircularVector a -> a
foldr1 = (a -> a -> a) -> CircularVector a -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
Foldable.foldr1

-- | @since 0.1
foldl1 :: (a -> a -> a) -> CircularVector a -> a
foldl1 :: (a -> a -> a) -> CircularVector a -> a
foldl1 = (a -> a -> a) -> CircularVector a -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
Foldable.foldl1

-- | @since 0.1
toNonEmpty :: CircularVector a -> NonEmpty a
toNonEmpty :: CircularVector a -> NonEmpty a
toNonEmpty = CircularVector a -> NonEmpty a
forall (t :: * -> *) a. Foldable1 t => t a -> NonEmpty a
Foldable1.toNonEmpty

-- | Lazily-accumulating semigroupoidal fold over
--   a 'CircularVector'.
--
--   @since 0.1
foldMap1 :: Semigroup m => (a -> m) -> CircularVector a -> m
foldMap1 :: (a -> m) -> CircularVector a -> m
foldMap1 a -> m
f = \CircularVector a
v ->
  let len :: Int
len = CircularVector a -> Int
forall a. CircularVector a -> Int
Data.Vector.Circular.length CircularVector 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 a -> Int -> a
forall a. CircularVector a -> Int -> a
index CircularVector 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 a -> a
forall a. CircularVector a -> a
last CircularVector a
v)
  in Int -> m
go Int
0
{-# inline foldMap1 #-}

-- | Strictly-accumulating semigroupoidal fold over
--   a 'CircularVector'.
--
--   @since 0.1
foldMap1' :: Semigroup m => (a -> m) -> CircularVector a -> m
foldMap1' :: (a -> m) -> CircularVector a -> m
foldMap1' a -> m
f = \CircularVector a
v ->
  let len :: Int
len = CircularVector a -> Int
forall a. CircularVector a -> Int
Data.Vector.Circular.length CircularVector 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 a -> Int -> a
forall a. CircularVector a -> Int -> a
index CircularVector a
v Int
ix))
        | Bool
otherwise = m
acc
  in Int -> m -> m
go Int
1 (a -> m
f (CircularVector a -> a
forall a. CircularVector a -> a
head CircularVector a
v))
{-# inline foldMap1' #-}

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

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

-- | /O(1)/ Construct a 'CircularVector' from a 'NonEmptyVector'.
--
--   @since 0.1
fromVector :: NonEmptyVector a -> CircularVector a
fromVector :: NonEmptyVector a -> CircularVector a
fromVector NonEmptyVector a
v = NonEmptyVector a -> Int -> CircularVector a
forall a. NonEmptyVector a -> Int -> CircularVector a
CircularVector NonEmptyVector a
v Int
0
{-# inline fromVector #-}

-- | /O(1)/ Construct a 'CircularVector' from a 'NonEmptyVector'.
--
--   @since 0.1.2
fromVector' :: Vector a -> Maybe (CircularVector a)
fromVector' :: Vector a -> Maybe (CircularVector a)
fromVector' Vector a
v = NonEmptyVector a -> Int -> CircularVector a
forall a. NonEmptyVector a -> Int -> CircularVector a
CircularVector (NonEmptyVector a -> Int -> CircularVector a)
-> Maybe (NonEmptyVector a) -> Maybe (Int -> CircularVector a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector a -> Maybe (NonEmptyVector a)
forall a. Vector a -> Maybe (NonEmptyVector a)
NonEmpty.fromVector Vector a
v Maybe (Int -> CircularVector a)
-> Maybe Int -> Maybe (CircularVector a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> Maybe Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
0
{-# inline fromVector' #-}

-- | /O(1)/ Construct a 'CircularVector' from a 'Vector'.
--
--   Calls @'error'@ if the input vector is empty.
--
--   @since 0.1
unsafeFromVector :: Vector a -> CircularVector a
unsafeFromVector :: Vector a -> CircularVector a
unsafeFromVector = NonEmptyVector a -> CircularVector a
forall a. NonEmptyVector a -> CircularVector a
fromVector (NonEmptyVector a -> CircularVector a)
-> (Vector a -> NonEmptyVector a) -> Vector a -> CircularVector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> NonEmptyVector a
forall a. Vector a -> NonEmptyVector a
NonEmpty.unsafeFromVector

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

-- | /O(n)/ Construct a 'CircularVector' from a list.
--
--   @since 0.1
fromList :: [a] -> Maybe (CircularVector a)
fromList :: [a] -> Maybe (CircularVector a)
fromList [a]
xs = Int -> [a] -> Maybe (CircularVector a)
forall a. Int -> [a] -> Maybe (CircularVector 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
fromListN :: Int -> [a] -> Maybe (CircularVector a)
fromListN :: Int -> [a] -> Maybe (CircularVector a)
fromListN Int
n [a]
xs = NonEmptyVector a -> CircularVector a
forall a. NonEmptyVector a -> CircularVector a
fromVector (NonEmptyVector a -> CircularVector a)
-> Maybe (NonEmptyVector a) -> Maybe (CircularVector a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> [a] -> Maybe (NonEmptyVector a)
forall a. Int -> [a] -> Maybe (NonEmptyVector a)
NonEmpty.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
unsafeFromList :: [a] -> CircularVector a
unsafeFromList :: [a] -> CircularVector a
unsafeFromList [a]
xs = Int -> [a] -> CircularVector a
forall a. Int -> [a] -> CircularVector 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
unsafeFromListN :: Int -> [a] -> CircularVector a
unsafeFromListN :: Int -> [a] -> CircularVector a
unsafeFromListN Int
n [a]
xs
  | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = String -> CircularVector a
forall a. HasCallStack => String -> a
error String
"Data.Vector.Circular.unsafeFromListN: invalid length!"
  | Bool
otherwise = Vector a -> CircularVector a
forall a. Vector a -> CircularVector a
unsafeFromVector (Int -> [a] -> Vector a
forall a. Int -> [a] -> Vector a
Vector.fromListN Int
n [a]
xs)

-- | /O(1)/ Construct a singleton 'CircularVector.
--
--   @since 0.1
singleton :: a -> CircularVector a
singleton :: a -> CircularVector a
singleton = NonEmptyVector a -> CircularVector a
forall a. NonEmptyVector a -> CircularVector a
fromVector (NonEmptyVector a -> CircularVector a)
-> (a -> NonEmptyVector a) -> a -> CircularVector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> NonEmptyVector a
forall a. a -> NonEmptyVector a
NonEmpty.singleton
{-# inline singleton #-}

-- | /O(1)/ Index into a 'CircularVector'. This is always total.
--
--   @since 0.1
index :: CircularVector a -> Int -> a
index :: CircularVector a -> Int -> a
index (CircularVector NonEmptyVector a
v Int
r) = \ !Int
ix ->
  let len :: Int
len = NonEmptyVector a -> Int
forall a. NonEmptyVector a -> Int
NonEmpty.length NonEmptyVector a
v
  in NonEmptyVector a -> Int -> a
forall a. NonEmptyVector a -> Int -> a
NonEmpty.unsafeIndex NonEmptyVector 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
head :: CircularVector a -> a
head :: CircularVector a -> a
head CircularVector a
v = CircularVector a -> Int -> a
forall a. CircularVector a -> Int -> a
index CircularVector a
v Int
0
{-# inline head #-}

-- | /O(1)/ Get the last element of a 'CircularVector'. This is always total.
--
--   @since 0.1
last :: CircularVector a -> a
last :: CircularVector a -> a
last CircularVector a
v = CircularVector a -> Int -> a
forall a. CircularVector a -> Int -> a
index CircularVector a
v (CircularVector a -> Int
forall a. CircularVector a -> Int
Data.Vector.Circular.length CircularVector 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
rotateRight :: Int -> CircularVector a -> CircularVector a
rotateRight :: Int -> CircularVector a -> CircularVector a
rotateRight Int
r' (CircularVector NonEmptyVector a
v Int
r) = NonEmptyVector a -> Int -> CircularVector a
forall a. NonEmptyVector a -> Int -> CircularVector a
CircularVector NonEmptyVector a
v Int
h
  where
    len :: Int
len = NonEmptyVector a -> Int
forall a. NonEmptyVector a -> Int
NonEmpty.length NonEmptyVector 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
rotateLeft :: Int -> CircularVector a -> CircularVector a
rotateLeft :: Int -> CircularVector a -> CircularVector a
rotateLeft Int
r' (CircularVector NonEmptyVector a
v Int
r) = NonEmptyVector a -> Int -> CircularVector a
forall a. NonEmptyVector a -> Int -> CircularVector a
CircularVector NonEmptyVector a
v Int
h
  where
    len :: Int
len = NonEmptyVector a -> Int
forall a. NonEmptyVector a -> Int
NonEmpty.length NonEmptyVector 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
vec :: Lift a => [a] -> Q (TExp (CircularVector a))
vec :: [a] -> Q (TExp (CircularVector a))
vec [] = String -> Q (TExp (CircularVector a))
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Cannot create an empty CircularVector!"
vec [a]
xs =
#if MIN_VERSION_template_haskell(2,16,0)
  CircularVector a -> Q (TExp (CircularVector a))
forall t. Lift t => t -> Q (TExp t)
liftTyped ([a] -> CircularVector a
forall a. [a] -> CircularVector a
unsafeFromList [a]
xs)
#else
  unsafeTExpCoerce [|unsafeFromList xs|]
#endif /* MIN_VERSION_template_haskell(2,16,0) */

-- | @since 0.1
equivalent :: Ord a => CircularVector a -> CircularVector a -> Bool
equivalent :: CircularVector a -> CircularVector a -> Bool
equivalent CircularVector a
x CircularVector a
y = CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
vector (CircularVector a -> CircularVector a
forall a. Ord a => CircularVector a -> CircularVector a
canonise CircularVector a
x) NonEmptyVector a -> NonEmptyVector a -> Bool
forall a. Eq a => a -> a -> Bool
== CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
vector (CircularVector a -> CircularVector a
forall a. Ord a => CircularVector a -> CircularVector a
canonise CircularVector a
y)

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

-- | @since 0.1
leastRotation :: forall a. (Ord a) => Vector a -> Int
leastRotation :: Vector a -> Int
leastRotation Vector 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 :: Vector a
s = Vector a
v Vector a -> Vector a -> Vector a
forall a. Semigroup a => a -> a -> a
<> Vector a
v
      let len :: Int
len = Vector a -> Int
forall a. Vector a -> Int
Vector.length Vector 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 <- Vector a -> Int -> ST s a
forall (m :: * -> *) a. Monad m => Vector a -> Int -> m a
Vector.indexM Vector 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 -> Vector a -> Int -> ST s a
forall (m :: * -> *) a. Monad m => Vector a -> Int -> m a
Vector.indexM Vector 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 -> Vector a -> Int -> ST s a
forall (m :: * -> *) a. Monad m => Vector a -> Int -> m a
Vector.indexM Vector 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
< (Vector a
s Vector a -> Int -> a
forall a. Vector a -> Int -> a
Vector.! 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.1
zipWith :: (a -> b -> c) -> CircularVector a -> CircularVector b -> CircularVector c
zipWith :: (a -> b -> c)
-> CircularVector a -> CircularVector b -> CircularVector c
zipWith a -> b -> c
f CircularVector a
a CircularVector b
b = NonEmptyVector c -> CircularVector c
forall a. NonEmptyVector a -> CircularVector a
fromVector (NonEmptyVector c -> CircularVector c)
-> NonEmptyVector c -> CircularVector c
forall a b. (a -> b) -> a -> b
$ (a -> b -> c)
-> NonEmptyVector a -> NonEmptyVector b -> NonEmptyVector c
forall a b c.
(a -> b -> c)
-> NonEmptyVector a -> NonEmptyVector b -> NonEmptyVector c
NonEmpty.zipWith a -> b -> c
f (CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector a
a) (CircularVector b -> NonEmptyVector b
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector b
b)

-- | Zip three circular vectors with the given function.
--
--   @since 0.1.1
zipWith3 :: (a -> b -> c -> d) -> CircularVector a -> CircularVector b -> CircularVector c
  -> CircularVector d
zipWith3 :: (a -> b -> c -> d)
-> CircularVector a
-> CircularVector b
-> CircularVector c
-> CircularVector d
zipWith3 a -> b -> c -> d
f CircularVector a
a CircularVector b
b CircularVector c
c = NonEmptyVector d -> CircularVector d
forall a. NonEmptyVector a -> CircularVector a
fromVector (NonEmptyVector d -> CircularVector d)
-> NonEmptyVector d -> CircularVector d
forall a b. (a -> b) -> a -> b
$
  (a -> b -> c -> d)
-> NonEmptyVector a
-> NonEmptyVector b
-> NonEmptyVector c
-> NonEmptyVector d
forall a b c d.
(a -> b -> c -> d)
-> NonEmptyVector a
-> NonEmptyVector b
-> NonEmptyVector c
-> NonEmptyVector d
NonEmpty.zipWith3 a -> b -> c -> d
f (CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector a
a) (CircularVector b -> NonEmptyVector b
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector b
b) (CircularVector c -> NonEmptyVector c
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector 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.1
zip :: CircularVector a -> CircularVector b -> CircularVector (a,b)
zip :: CircularVector a -> CircularVector b -> CircularVector (a, b)
zip CircularVector a
a CircularVector b
b = NonEmptyVector (a, b) -> CircularVector (a, b)
forall a. NonEmptyVector a -> CircularVector a
fromVector (NonEmptyVector (a, b) -> CircularVector (a, b))
-> NonEmptyVector (a, b) -> CircularVector (a, b)
forall a b. (a -> b) -> a -> b
$ NonEmptyVector a -> NonEmptyVector b -> NonEmptyVector (a, b)
forall a b.
NonEmptyVector a -> NonEmptyVector b -> NonEmptyVector (a, b)
NonEmpty.zip (CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector a
a) (CircularVector b -> NonEmptyVector b
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector b
b)

-- | Zip together three circular vectors.
--
--   @since 0.1.1
zip3 :: CircularVector a -> CircularVector b -> CircularVector c -> CircularVector (a,b,c)
zip3 :: CircularVector a
-> CircularVector b -> CircularVector c -> CircularVector (a, b, c)
zip3 CircularVector a
a CircularVector b
b CircularVector c
c = NonEmptyVector (a, b, c) -> CircularVector (a, b, c)
forall a. NonEmptyVector a -> CircularVector a
fromVector (NonEmptyVector (a, b, c) -> CircularVector (a, b, c))
-> NonEmptyVector (a, b, c) -> CircularVector (a, b, c)
forall a b. (a -> b) -> a -> b
$ NonEmptyVector a
-> NonEmptyVector b -> NonEmptyVector c -> NonEmptyVector (a, b, c)
forall a b c.
NonEmptyVector a
-> NonEmptyVector b -> NonEmptyVector c -> NonEmptyVector (a, b, c)
NonEmpty.zip3 (CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector a
a) (CircularVector b -> NonEmptyVector b
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector b
b) (CircularVector c -> NonEmptyVector c
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector c
c)

-- | /O(n)/ Reverse a circular vector.
--
--   @since 0.1.1
reverse :: CircularVector a -> CircularVector a
reverse :: CircularVector a -> CircularVector a
reverse = NonEmptyVector a -> CircularVector a
forall a. NonEmptyVector a -> CircularVector a
fromVector (NonEmptyVector a -> CircularVector a)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> CircularVector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmptyVector a -> NonEmptyVector a
forall a. NonEmptyVector a -> NonEmptyVector a
NonEmpty.reverse (NonEmptyVector a -> NonEmptyVector a)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> NonEmptyVector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

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

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

-- | /O(n)/ Check if all elements satisfy the predicate.
--
--   @since 0.1.1
all :: (a -> Bool) -> CircularVector a -> Bool
all :: (a -> Bool) -> CircularVector a -> Bool
all a -> Bool
f = (a -> Bool) -> NonEmptyVector a -> Bool
forall a. (a -> Bool) -> NonEmptyVector a -> Bool
NonEmpty.all a -> Bool
f (NonEmptyVector a -> Bool)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
vector

-- | /O(n)/ Check if any element satisfies the predicate.
--
--   @since 0.1.1
any :: (a -> Bool) -> CircularVector a -> Bool
any :: (a -> Bool) -> CircularVector a -> Bool
any a -> Bool
f = (a -> Bool) -> NonEmptyVector a -> Bool
forall a. (a -> Bool) -> NonEmptyVector a -> Bool
NonEmpty.any a -> Bool
f (NonEmptyVector a -> Bool)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
vector

-- | /O(n)/ Check if all elements are True.
--
--   @since 0.1.1
and :: CircularVector Bool -> Bool
and :: CircularVector Bool -> Bool
and = NonEmptyVector Bool -> Bool
NonEmpty.and (NonEmptyVector Bool -> Bool)
-> (CircularVector Bool -> NonEmptyVector Bool)
-> CircularVector Bool
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector Bool -> NonEmptyVector Bool
forall a. CircularVector a -> NonEmptyVector a
vector

-- | /O(n)/ Check if any element is True.
--
--   @since 0.1.1
or :: CircularVector Bool -> Bool
or :: CircularVector Bool -> Bool
or = NonEmptyVector Bool -> Bool
NonEmpty.or (NonEmptyVector Bool -> Bool)
-> (CircularVector Bool -> NonEmptyVector Bool)
-> CircularVector Bool
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector Bool -> NonEmptyVector Bool
forall a. CircularVector a -> NonEmptyVector a
vector

-- | /O(n)/ Compute the sum of the elements.
--
--   @since 0.1.1
sum :: Num a => CircularVector a -> a
sum :: CircularVector a -> a
sum = NonEmptyVector a -> a
forall a. Num a => NonEmptyVector a -> a
NonEmpty.sum (NonEmptyVector a -> a)
-> (CircularVector a -> NonEmptyVector a) -> CircularVector a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
vector

-- | /O(n)/ Compute the product of the elements.
--
--   @since 0.1.1
product :: Num a => CircularVector a -> a
product :: CircularVector a -> a
product = NonEmptyVector a -> a
forall a. Num a => NonEmptyVector a -> a
NonEmpty.sum (NonEmptyVector a -> a)
-> (CircularVector a -> NonEmptyVector a) -> CircularVector a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
vector

-- | /O(n)/ Yield the maximum element of the circular vector.
--
--   @since 0.1.1
maximum :: Ord a => CircularVector a -> a
maximum :: CircularVector a -> a
maximum = NonEmptyVector a -> a
forall a. Ord a => NonEmptyVector a -> a
NonEmpty.maximum (NonEmptyVector a -> a)
-> (CircularVector a -> NonEmptyVector a) -> CircularVector a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
vector

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

-- | /O(n)/ Yield the minimum element of the circular vector.
--
--   @since 0.1.1
minimum :: Ord a => CircularVector a -> a
minimum :: CircularVector a -> a
minimum = NonEmptyVector a -> a
forall a. Ord a => NonEmptyVector a -> a
NonEmpty.minimum (NonEmptyVector a -> a)
-> (CircularVector a -> NonEmptyVector a) -> CircularVector a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
vector

-- | /O(n)/ Yield the minimum element of a circular vector according to the
--   given comparison function.
--
--   @since 0.1.1
minimumBy :: (a -> a -> Ordering) -> CircularVector a -> a
minimumBy :: (a -> a -> Ordering) -> CircularVector a -> a
minimumBy a -> a -> Ordering
f = (a -> a -> Ordering) -> NonEmptyVector a -> a
forall a. (a -> a -> Ordering) -> NonEmptyVector a -> a
NonEmpty.minimumBy a -> a -> Ordering
f (NonEmptyVector a -> a)
-> (CircularVector a -> NonEmptyVector a) -> CircularVector a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector 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 3 "a"
-- Just (CircularVector {vector = ["a","a","a"], rotation = 0})
--
-- >>> replicate 0 "a"
-- Nothing
--
replicate :: Int -> a -> Maybe (CircularVector a)
replicate :: Int -> a -> Maybe (CircularVector a)
replicate Int
n a
a = Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' (Int -> a -> Vector a
forall a. Int -> a -> Vector a
Vector.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
--
-- >>> replicate1 3 "a"
-- CircularVector {vector = ["a","a","a"], rotation = 0}
--
-- >>> replicate1 0 "a"
-- CircularVector {vector = ["a"], rotation = 0}
--
-- >>> replicate1 (-1) "a"
-- CircularVector {vector = ["a"], rotation = 0}
replicate1 :: Int -> a -> CircularVector a
replicate1 :: Int -> a -> CircularVector a
replicate1 Int
n a
a = Vector a -> CircularVector a
forall a. Vector a -> CircularVector a
unsafeFromVector (Int -> a -> Vector a
forall a. Int -> a -> Vector a
Vector.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 1 f
-- Just (CircularVector {vector = ["a"], rotation = 0})
--
-- >>> generate 0 f
-- Nothing
--
-- >>> generate 2 f
-- Just (CircularVector {vector = ["a","k"], rotation = 0})
--
generate :: Int -> (Int -> a) -> Maybe (CircularVector a)
generate :: Int -> (Int -> a) -> Maybe (CircularVector a)
generate Int
n Int -> a
f = Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' (Int -> (Int -> a) -> Vector a
forall a. Int -> (Int -> a) -> Vector a
Vector.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 2 f
-- ["a","k"]
--
-- >>> toList $ generate1 0 f
-- ["a"]
--
-- >>> toList $ generate1 (-1) f
-- ["a"]
--
generate1 :: Int -> (Int -> a) -> CircularVector a
generate1 :: Int -> (Int -> a) -> CircularVector a
generate1 Int
n Int -> a
f = Vector a -> CircularVector a
forall a. Vector a -> CircularVector a
unsafeFromVector (Int -> (Int -> a) -> Vector a
forall a. Int -> (Int -> a) -> Vector a
Vector.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 3 (+1) 0
-- Just (CircularVector {vector = [0,1,2], rotation = 0})
--
-- >>> iterateN 0 (+1) 0
-- Nothing
--
-- >>> iterateN (-1) (+1) 0
-- Nothing
--
iterateN :: Int -> (a -> a) -> a -> Maybe (CircularVector a)
iterateN :: Int -> (a -> a) -> a -> Maybe (CircularVector a)
iterateN Int
n a -> a
f a
a = Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' (Int -> (a -> a) -> a -> Vector a
forall a. Int -> (a -> a) -> a -> Vector a
Vector.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 3 (+1) 0
-- CircularVector {vector = [0,1,2], rotation = 0}
--
-- >>> iterateN1 0 (+1) 0
-- CircularVector {vector = [0], rotation = 0}
--
-- >>> iterateN1 (-1) (+1) 0
-- CircularVector {vector = [0], rotation = 0}
--
iterateN1 :: Int -> (a -> a) -> a -> CircularVector a
iterateN1 :: Int -> (a -> a) -> a -> CircularVector a
iterateN1 Int
n a -> a
f a
a = Vector a -> CircularVector a
forall a. Vector a -> CircularVector a
unsafeFromVector (Int -> (a -> a) -> a -> Vector a
forall a. Int -> (a -> a) -> a -> Vector a
Vector.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 3 (Just "a")
-- Just (Just (CircularVector {vector = ["a","a","a"], rotation = 0}))
--
-- >>> replicateM @Maybe 3 Nothing
-- Nothing
--
-- >>> replicateM @Maybe 0 (Just "a")
-- Just Nothing
--
-- >>> replicateM @Maybe (-1) (Just "a")
-- Just Nothing
--
replicateM :: Monad m => Int -> m a -> m (Maybe (CircularVector a))
replicateM :: Int -> m a -> m (Maybe (CircularVector a))
replicateM Int
n m a
a = (Vector a -> Maybe (CircularVector a))
-> m (Vector a) -> m (Maybe (CircularVector a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' (Int -> m a -> m (Vector a)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
Vector.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 3 (Just "a")
-- Just (CircularVector {vector = ["a","a","a"], rotation = 0})
--
-- >>> replicate1M @Maybe 3 Nothing
-- Nothing
--
-- >>> replicate1M @Maybe 0 (Just "a")
-- Just (CircularVector {vector = ["a"], rotation = 0})
--
-- >>> replicate1M @Maybe (-1) (Just "a")
-- Just (CircularVector {vector = ["a"], rotation = 0})
--
replicate1M :: Monad m => Int -> m a -> m (CircularVector a)
replicate1M :: Int -> m a -> m (CircularVector a)
replicate1M Int
n m a
a = (Vector a -> CircularVector a)
-> m (Vector a) -> m (CircularVector a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector a -> CircularVector a
forall a. Vector a -> CircularVector a
unsafeFromVector (Int -> m a -> m (Vector a)
forall (m :: * -> *) a. Monad m => Int -> m a -> m (Vector a)
Vector.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 3 (\i -> if i < 1 then ["a"] else ["b"])
-- [Just (CircularVector {vector = ["a","b","b"], rotation = 0})]
--
-- >>> generateM @[] @Int 3 (const [])
-- []
--
-- >>> generateM @[] @Int 0 (const [1])
-- [Nothing]
--
-- >>> generateM @Maybe @Int (-1) (const Nothing)
-- Just Nothing
--
generateM :: Monad m => Int -> (Int -> m a) -> m (Maybe (CircularVector a))
generateM :: Int -> (Int -> m a) -> m (Maybe (CircularVector a))
generateM Int
n Int -> m a
f = (Vector a -> Maybe (CircularVector a))
-> m (Vector a) -> m (Maybe (CircularVector a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' (Int -> (Int -> m a) -> m (Vector a)
forall (m :: * -> *) a.
Monad m =>
Int -> (Int -> m a) -> m (Vector a)
Vector.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 3 (\i -> if i < 1 then Just "a" else Just "b")
-- Just (CircularVector {vector = ["a","b","b"], rotation = 0})
--
-- >>> generate1M 3 (const [])
-- []
--
-- >>> generate1M 0 (const $ Just 1)
-- Just (CircularVector {vector = [1], rotation = 0})
--
-- >>> generate1M (-1) (const Nothing)
-- Nothing
--
generate1M :: Monad m => Int -> (Int -> m a) -> m (CircularVector a)
generate1M :: Int -> (Int -> m a) -> m (CircularVector a)
generate1M Int
n Int -> m a
f = (Vector a -> CircularVector a)
-> m (Vector a) -> m (CircularVector a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector a -> CircularVector a
forall a. Vector a -> CircularVector a
unsafeFromVector (Int -> (Int -> m a) -> m (Vector a)
forall (m :: * -> *) a.
Monad m =>
Int -> (Int -> m a) -> m (Vector a)
Vector.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 3 return "a"
-- Just (Just (CircularVector {vector = ["a","a","a"], rotation = 0}))
--
-- >>> iterateNM @Maybe 3 (const Nothing) "a"
-- Nothing
--
-- >>> iterateNM @Maybe 0 return "a"
-- Just Nothing
--
iterateNM :: Monad m => Int -> (a -> m a) -> a -> m (Maybe (CircularVector a))
iterateNM :: Int -> (a -> m a) -> a -> m (Maybe (CircularVector a))
iterateNM Int
n a -> m a
f a
a = (Vector a -> Maybe (CircularVector a))
-> m (Vector a) -> m (Maybe (CircularVector a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' (Int -> (a -> m a) -> a -> m (Vector a)
forall (m :: * -> *) a.
Monad m =>
Int -> (a -> m a) -> a -> m (Vector a)
Vector.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 3 return "a"
-- Just (CircularVector {vector = ["a","a","a"], rotation = 0})
--
-- >>> iterateN1M @Maybe 3 (const Nothing) "a"
-- Nothing
--
-- >>> iterateN1M @Maybe 0 return "a"
-- Just (CircularVector {vector = ["a"], rotation = 0})
--
-- >>> iterateN1M @Maybe (-1) return "a"
-- Just (CircularVector {vector = ["a"], rotation = 0})
--
iterateN1M :: Monad m => Int -> (a -> m a) -> a -> m (CircularVector a)
iterateN1M :: Int -> (a -> m a) -> a -> m (CircularVector a)
iterateN1M Int
n a -> m a
f a
a = (Vector a -> CircularVector a)
-> m (Vector a) -> m (CircularVector a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector a -> CircularVector a
forall a. Vector a -> CircularVector a
unsafeFromVector (Int -> (a -> m a) -> a -> m (Vector a)
forall (m :: * -> *) a.
Monad m =>
Int -> (a -> m a) -> a -> m (Vector a)
Vector.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 :: (forall s. ST s (MVector.MVector s a)) -> Maybe (CircularVector a)
create :: (forall s. ST s (MVector s a)) -> Maybe (CircularVector a)
create forall s. ST s (MVector s a)
p = Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' ((forall s. ST s (MVector s a)) -> Vector a
forall a. (forall s. ST s (MVector s a)) -> Vector a
Vector.create forall s. ST s (MVector 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 :: (forall s. ST s (MVector.MVector s a)) -> CircularVector a
unsafeCreate :: (forall s. ST s (MVector s a)) -> CircularVector a
unsafeCreate forall s. ST s (MVector s a)
p = Vector a -> CircularVector a
forall a. Vector a -> CircularVector a
unsafeFromVector ((forall s. ST s (MVector s a)) -> Vector a
forall a. (forall s. ST s (MVector s a)) -> Vector a
Vector.create forall s. ST s (MVector s a)
p)

-- | Execute the monadic action and freeze the resulting circular vector.
--
--   @since 0.1.2
createT
    :: Traversable t
    => (forall s. ST s (t (MVector.MVector s a)))
    -> t (Maybe (CircularVector a))
createT :: (forall s. ST s (t (MVector s a))) -> t (Maybe (CircularVector a))
createT forall s. ST s (t (MVector s a))
p = (Vector a -> Maybe (CircularVector a))
-> t (Vector a) -> t (Maybe (CircularVector a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' ((forall s. ST s (t (MVector s a))) -> t (Vector a)
forall (f :: * -> *) a.
Traversable f =>
(forall s. ST s (f (MVector s a))) -> f (Vector a)
Vector.createT forall s. ST s (t (MVector 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
    => (forall s. ST s (t (MVector.MVector s a)))
    -> t (CircularVector a)
unsafeCreateT :: (forall s. ST s (t (MVector s a))) -> t (CircularVector a)
unsafeCreateT forall s. ST s (t (MVector s a))
p = (Vector a -> CircularVector a)
-> t (Vector a) -> t (CircularVector a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector a -> CircularVector a
forall a. Vector a -> CircularVector a
unsafeFromVector ((forall s. ST s (t (MVector s a))) -> t (Vector a)
forall (f :: * -> *) a.
Traversable f =>
(forall s. ST s (f (MVector s a))) -> f (Vector a)
Vector.createT forall s. ST s (t (MVector 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 (\b -> case b of "a" -> Just ("a", "b"); _ ->  Nothing) "a"
-- Just (CircularVector {vector = ["a"], rotation = 0})
--
-- >>> unfoldr (const Nothing) "a"
-- Nothing
--
unfoldr :: (b -> Maybe (a, b)) -> b -> Maybe (CircularVector a)
unfoldr :: (b -> Maybe (a, b)) -> b -> Maybe (CircularVector a)
unfoldr b -> Maybe (a, b)
f b
b = Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' ((b -> Maybe (a, b)) -> b -> Vector a
forall b a. (b -> Maybe (a, b)) -> b -> Vector a
Vector.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 (\b -> case b of "a" -> Just ("a", "b"); _ ->  Nothing) "first" "a"
-- CircularVector {vector = ["first","a"], rotation = 0}
--
-- >>> unfoldr1 (const Nothing) "first" "a"
-- CircularVector {vector = ["first"], rotation = 0}
--
unfoldr1 :: (b -> Maybe (a, b)) -> a -> b -> CircularVector a
unfoldr1 :: (b -> Maybe (a, b)) -> a -> b -> CircularVector a
unfoldr1 b -> Maybe (a, b)
f a
a b
b = a -> CircularVector a -> CircularVector a
forall a. a -> CircularVector a -> CircularVector a
cons a
a (Vector a -> CircularVector a
forall a. Vector a -> CircularVector a
unsafeFromVector ((b -> Maybe (a, b)) -> b -> Vector a
forall b a. (b -> Maybe (a, b)) -> b -> Vector a
Vector.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 3 (\b -> Just (b+1, b+1)) 0
-- Just (CircularVector {vector = [1,2,3], rotation = 0})
--
-- >>> unfoldrN 3 (const Nothing) 0
-- Nothing
--
-- >>> unfoldrN 0 (\b -> Just (b+1, b+1)) 0
-- Nothing
--
unfoldrN :: Int -> (b -> Maybe (a, b)) -> b -> Maybe (CircularVector a)
unfoldrN :: Int -> (b -> Maybe (a, b)) -> b -> Maybe (CircularVector a)
unfoldrN Int
n b -> Maybe (a, b)
f b
b = Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' (Int -> (b -> Maybe (a, b)) -> b -> Vector a
forall b a. Int -> (b -> Maybe (a, b)) -> b -> Vector a
Vector.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 3 (\b -> Just (b+1, b+1)) 0 0
-- CircularVector {vector = [0,1,2,3], rotation = 0}
--
-- >>> unfoldr1N 3 (const Nothing) 0 0
-- CircularVector {vector = [0], rotation = 0}
--
-- >>> unfoldr1N 0 (\b -> Just (b+1, b+1)) 0 0
-- CircularVector {vector = [0], rotation = 0}
--
unfoldr1N
    :: Int
    -> (b -> Maybe (a, b))
    -> a
    -> b
    -> CircularVector a
unfoldr1N :: Int -> (b -> Maybe (a, b)) -> a -> b -> CircularVector a
unfoldr1N Int
n b -> Maybe (a, b)
f a
a b
b = a -> CircularVector a -> CircularVector a
forall a. a -> CircularVector a -> CircularVector a
cons a
a (Vector a -> CircularVector a
forall a. Vector a -> CircularVector a
unsafeFromVector (Int -> (b -> Maybe (a, b)) -> b -> Vector a
forall b a. Int -> (b -> Maybe (a, b)) -> b -> Vector a
Vector.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
    => (b -> m (Maybe (a, b)))
    -> b
    -> m (Maybe (CircularVector a))
unfoldrM :: (b -> m (Maybe (a, b))) -> b -> m (Maybe (CircularVector a))
unfoldrM b -> m (Maybe (a, b))
f b
b = (Vector a -> Maybe (CircularVector a))
-> m (Vector a) -> m (Maybe (CircularVector a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' ((b -> m (Maybe (a, b))) -> b -> m (Vector a)
forall (m :: * -> *) b a.
Monad m =>
(b -> m (Maybe (a, b))) -> b -> m (Vector a)
Vector.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
    => (b -> m (Maybe (a, b)))
    -> a
    -> b
    -> m (CircularVector a)
unfoldr1M :: (b -> m (Maybe (a, b))) -> a -> b -> m (CircularVector a)
unfoldr1M b -> m (Maybe (a, b))
f a
a b
b = (Vector a -> CircularVector a)
-> m (Vector a) -> m (CircularVector a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> CircularVector a -> CircularVector a
forall a. a -> CircularVector a -> CircularVector a
cons a
a (CircularVector a -> CircularVector a)
-> (Vector a -> CircularVector a) -> Vector a -> CircularVector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> CircularVector a
forall a. Vector a -> CircularVector a
unsafeFromVector) ((b -> m (Maybe (a, b))) -> b -> m (Vector a)
forall (m :: * -> *) b a.
Monad m =>
(b -> m (Maybe (a, b))) -> b -> m (Vector a)
Vector.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
    => Int
    -> (b -> m (Maybe (a, b)))
    -> b
    -> m (Maybe (CircularVector a))
unfoldrNM :: Int -> (b -> m (Maybe (a, b))) -> b -> m (Maybe (CircularVector a))
unfoldrNM Int
n b -> m (Maybe (a, b))
f b
b = (Vector a -> Maybe (CircularVector a))
-> m (Vector a) -> m (Maybe (CircularVector a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' (Int -> (b -> m (Maybe (a, b))) -> b -> m (Vector a)
forall (m :: * -> *) b a.
Monad m =>
Int -> (b -> m (Maybe (a, b))) -> b -> m (Vector a)
Vector.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
    => Int
    -> (b -> m (Maybe (a, b)))
    -> a
    -> b
    -> m (CircularVector a)
unfoldr1NM :: Int -> (b -> m (Maybe (a, b))) -> a -> b -> m (CircularVector a)
unfoldr1NM Int
n b -> m (Maybe (a, b))
f a
a b
b = (Vector a -> CircularVector a)
-> m (Vector a) -> m (CircularVector a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> CircularVector a -> CircularVector a
forall a. a -> CircularVector a -> CircularVector a
cons a
a (CircularVector a -> CircularVector a)
-> (Vector a -> CircularVector a) -> Vector a -> CircularVector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> CircularVector a
forall a. Vector a -> CircularVector a
unsafeFromVector) (Int -> (b -> m (Maybe (a, b))) -> b -> m (Vector a)
forall (m :: * -> *) b a.
Monad m =>
Int -> (b -> m (Maybe (a, b))) -> b -> m (Vector a)
Vector.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 :: Int -> (Vector a -> a) -> Maybe (CircularVector a)
constructN :: Int -> (Vector a -> a) -> Maybe (CircularVector a)
constructN Int
n Vector a -> a
f = Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' (Int -> (Vector a -> a) -> Vector a
forall a. Int -> (Vector a -> a) -> Vector a
Vector.constructN Int
n Vector 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 :: Int -> (Vector a -> a) -> Maybe (CircularVector a)
constructrN :: Int -> (Vector a -> a) -> Maybe (CircularVector a)
constructrN Int
n Vector a -> a
f = Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' (Int -> (Vector a -> a) -> Vector a
forall a. Int -> (Vector a -> a) -> Vector a
Vector.constructrN Int
n Vector 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 :: Num a => a -> Int -> Maybe (CircularVector a)
enumFromN :: a -> Int -> Maybe (CircularVector a)
enumFromN a
a Int
n = Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' (a -> Int -> Vector a
forall a. Num a => a -> Int -> Vector a
Vector.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 :: Num a => a -> Int -> CircularVector a
enumFromN1 :: a -> Int -> CircularVector a
enumFromN1 a
a Int
n = Vector a -> CircularVector a
forall a. Vector a -> CircularVector a
unsafeFromVector (a -> Int -> Vector a
forall a. Num a => a -> Int -> Vector a
Vector.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 :: Num a => a -> a -> Int -> Maybe (CircularVector a)
enumFromStepN :: a -> a -> Int -> Maybe (CircularVector a)
enumFromStepN a
a0 a
a1 Int
n = Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' (a -> a -> Int -> Vector a
forall a. Num a => a -> a -> Int -> Vector a
Vector.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 :: Num a => a -> a -> Int -> CircularVector a
enumFromStepN1 :: a -> a -> Int -> CircularVector a
enumFromStepN1 a
a0 a
a1 Int
n = Vector a -> CircularVector a
forall a. Vector a -> CircularVector a
unsafeFromVector (a -> a -> Int -> Vector a
forall a. Num a => a -> a -> Int -> Vector a
Vector.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 :: Enum a => a -> a -> Maybe (CircularVector a)
enumFromTo :: a -> a -> Maybe (CircularVector a)
enumFromTo a
a0 a
a1 = Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' (a -> a -> Vector a
forall a. Enum a => a -> a -> Vector a
Vector.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 :: Enum a => a -> a -> a -> Maybe (CircularVector a)
enumFromThenTo :: a -> a -> a -> Maybe (CircularVector a)
enumFromThenTo a
a0 a
a1 a
a2 = Vector a -> Maybe (CircularVector a)
forall a. Vector a -> Maybe (CircularVector a)
fromVector' (a -> a -> a -> Vector a
forall a. Enum a => a -> a -> a -> Vector a
Vector.enumFromThenTo a
a0 a
a1 a
a2)

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

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

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

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

-- | /O(m+n)/ Concatenate two circular vectors
--
--   @since 0.1.2
--
-- >>> (unsafeFromList [1..3]) ++ (unsafeFromList [4..6])
-- CircularVector {vector = [1,2,3,4,5,6], rotation = 0}
--
(++) :: CircularVector a -> CircularVector a -> CircularVector a
CircularVector a
v ++ :: CircularVector a -> CircularVector a -> CircularVector a
++ CircularVector a
v' = NonEmptyVector a -> CircularVector a
forall a. NonEmptyVector a -> CircularVector a
fromVector (CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector a
v NonEmptyVector a -> NonEmptyVector a -> NonEmptyVector a
forall a. NonEmptyVector a -> NonEmptyVector a -> NonEmptyVector a
NonEmpty.++ CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector 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 [1..3]), (unsafeFromList [4..6])]
-- Just (CircularVector {vector = [1,2,3,4,5,6], rotation = 0})
--
concat :: [CircularVector a] -> Maybe (CircularVector a)
concat :: [CircularVector a] -> Maybe (CircularVector a)
concat [] = Maybe (CircularVector a)
forall a. Maybe a
Nothing
concat (CircularVector a
a:[CircularVector a]
as) = CircularVector a -> Maybe (CircularVector a)
forall a. a -> Maybe a
Just (NonEmpty (CircularVector a) -> CircularVector a
forall a. NonEmpty (CircularVector a) -> CircularVector a
concat1 (CircularVector a
a CircularVector a
-> [CircularVector a] -> NonEmpty (CircularVector a)
forall a. a -> [a] -> NonEmpty a
:| [CircularVector a]
as))
{-# INLINE concat #-}

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

-- | /O(n)/ Map a function over a circular vector.
--
--   @since 0.1.2
--
-- >>> map (+1) $ unsafeFromList [1..3]
-- CircularVector {vector = [2,3,4], rotation = 0}
--
map :: (a -> b) -> CircularVector a -> CircularVector b
map :: (a -> b) -> CircularVector a -> CircularVector b
map a -> b
f (CircularVector NonEmptyVector a
v Int
rot) = NonEmptyVector b -> Int -> CircularVector b
forall a. NonEmptyVector a -> Int -> CircularVector a
CircularVector ((a -> b) -> NonEmptyVector a -> NonEmptyVector b
forall a b. (a -> b) -> NonEmptyVector a -> NonEmptyVector b
NonEmpty.map a -> b
f NonEmptyVector 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 [1..3]
-- CircularVector {vector = [1,2,4], rotation = 0}
--
imap :: (Int -> a -> b) -> CircularVector a -> CircularVector b
imap :: (Int -> a -> b) -> CircularVector a -> CircularVector b
imap Int -> a -> b
f = NonEmptyVector b -> CircularVector b
forall a. NonEmptyVector a -> CircularVector a
fromVector (NonEmptyVector b -> CircularVector b)
-> (CircularVector a -> NonEmptyVector b)
-> CircularVector a
-> CircularVector b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> a -> b) -> NonEmptyVector a -> NonEmptyVector b
forall a b. (Int -> a -> b) -> NonEmptyVector a -> NonEmptyVector b
NonEmpty.imap Int -> a -> b
f (NonEmptyVector a -> NonEmptyVector b)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> NonEmptyVector b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | Map a function over a circular vector and concatenate the results.
--
--   @since 0.1.2
--
-- >>> concatMap (\a -> unsafeFromList [a,a]) (unsafeFromList [1,2,3])
-- CircularVector {vector = [1,1,2,2,3,3], rotation = 0}
--
concatMap
    :: (a -> CircularVector b)
    -> CircularVector a
    -> CircularVector b
concatMap :: (a -> CircularVector b) -> CircularVector a -> CircularVector b
concatMap a -> CircularVector b
f = NonEmptyVector b -> CircularVector b
forall a. NonEmptyVector a -> CircularVector a
fromVector (NonEmptyVector b -> CircularVector b)
-> (CircularVector a -> NonEmptyVector b)
-> CircularVector a
-> CircularVector b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> NonEmptyVector b) -> NonEmptyVector a -> NonEmptyVector b
forall a b.
(a -> NonEmptyVector b) -> NonEmptyVector a -> NonEmptyVector b
NonEmpty.concatMap (CircularVector b -> NonEmptyVector b
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector (CircularVector b -> NonEmptyVector b)
-> (a -> CircularVector b) -> a -> NonEmptyVector b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> CircularVector b
f) (NonEmptyVector a -> NonEmptyVector b)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> NonEmptyVector b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 [1..3])
-- Just (CircularVector {vector = [1,2,3], rotation = 0})
--
-- >>> mapM (const Nothing) (unsafeFromList [1..3])
-- Nothing
--
mapM :: Monad m => (a -> m b) -> CircularVector a -> m (CircularVector b)
mapM :: (a -> m b) -> CircularVector a -> m (CircularVector b)
mapM a -> m b
f = (NonEmptyVector b -> CircularVector b)
-> m (NonEmptyVector b) -> m (CircularVector b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NonEmptyVector b -> CircularVector b
forall a. NonEmptyVector a -> CircularVector a
fromVector (m (NonEmptyVector b) -> m (CircularVector b))
-> (CircularVector a -> m (NonEmptyVector b))
-> CircularVector a
-> m (CircularVector b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> m b) -> NonEmptyVector a -> m (NonEmptyVector b)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> NonEmptyVector a -> m (NonEmptyVector b)
NonEmpty.mapM a -> m b
f (NonEmptyVector a -> m (NonEmptyVector b))
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> m (NonEmptyVector b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 [1..3])
-- Just (CircularVector {vector = [0,2,0], rotation = 0})
--
-- >>> imapM (\_ _ -> Nothing) (unsafeFromList [1..3])
-- Nothing
--
imapM
    :: Monad m
    => (Int -> a -> m b)
    -> CircularVector a
    -> m (CircularVector b)
imapM :: (Int -> a -> m b) -> CircularVector a -> m (CircularVector b)
imapM Int -> a -> m b
f = (NonEmptyVector b -> CircularVector b)
-> m (NonEmptyVector b) -> m (CircularVector b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NonEmptyVector b -> CircularVector b
forall a. NonEmptyVector a -> CircularVector a
fromVector (m (NonEmptyVector b) -> m (CircularVector b))
-> (CircularVector a -> m (NonEmptyVector b))
-> CircularVector a
-> m (CircularVector b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> a -> m b) -> NonEmptyVector a -> m (NonEmptyVector b)
forall (m :: * -> *) a b.
Monad m =>
(Int -> a -> m b) -> NonEmptyVector a -> m (NonEmptyVector b)
NonEmpty.imapM Int -> a -> m b
f (NonEmptyVector a -> m (NonEmptyVector b))
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> m (NonEmptyVector b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 [1..3])
-- Just ()
--
-- >>> mapM_ (const Nothing) (unsafeFromList [1..3])
-- Nothing
--
mapM_ :: Monad m => (a -> m b) -> CircularVector a -> m ()
mapM_ :: (a -> m b) -> CircularVector a -> m ()
mapM_ a -> m b
f = (a -> m b) -> NonEmptyVector a -> m ()
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> NonEmptyVector a -> m ()
NonEmpty.mapM_ a -> m b
f (NonEmptyVector a -> m ())
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 [1..3])
-- 0
-- 2
-- 0
--
-- >>> imapM_ (\_ _ -> Nothing) (unsafeFromList [1..3])
-- Nothing
--
imapM_ :: Monad m => (Int -> a -> m b) -> CircularVector a -> m ()
imapM_ :: (Int -> a -> m b) -> CircularVector a -> m ()
imapM_ Int -> a -> m b
f = (Int -> a -> m b) -> NonEmptyVector a -> m ()
forall (m :: * -> *) a b.
Monad m =>
(Int -> a -> m b) -> NonEmptyVector a -> m ()
NonEmpty.imapM_ Int -> a -> m b
f (NonEmptyVector a -> m ())
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 => CircularVector a -> (a -> m b) -> m (CircularVector b)
forM :: CircularVector a -> (a -> m b) -> m (CircularVector b)
forM CircularVector a
cv a -> m b
f = NonEmptyVector b -> CircularVector b
forall a. NonEmptyVector a -> CircularVector a
fromVector (NonEmptyVector b -> CircularVector b)
-> m (NonEmptyVector b) -> m (CircularVector b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmptyVector a -> (a -> m b) -> m (NonEmptyVector b)
forall (m :: * -> *) a b.
Monad m =>
NonEmptyVector a -> (a -> m b) -> m (NonEmptyVector b)
NonEmpty.forM (CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector 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 => CircularVector a -> (a -> m b) -> m ()
forM_ :: CircularVector a -> (a -> m b) -> m ()
forM_ CircularVector a
cv a -> m b
f = NonEmptyVector a -> (a -> m b) -> m ()
forall (m :: * -> *) a b.
Monad m =>
NonEmptyVector a -> (a -> m b) -> m ()
NonEmpty.forM_ (CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector a
cv) a -> m b
f

-- | /O(n)/ Drop repeated adjacent elements.
--
-- >>> toList $ uniq $ unsafeFromList [1,1,2,2,3,3,1]
-- [1,2,3]
--
-- >>> toList $ uniq $ unsafeFromList [1,2,3,1]
-- [1,2,3]
--
-- >>> toList $ uniq $ unsafeFromList [1]
-- [1]
uniq :: Eq a => CircularVector a -> CircularVector a
uniq :: CircularVector a -> CircularVector a
uniq = NonEmptyVector a -> CircularVector a
forall a. NonEmptyVector a -> CircularVector a
fromVector (NonEmptyVector a -> CircularVector a)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> CircularVector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmptyVector a -> NonEmptyVector a
forall a. Eq a => NonEmptyVector a -> NonEmptyVector a
trim (NonEmptyVector a -> NonEmptyVector a)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> NonEmptyVector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmptyVector a -> NonEmptyVector a
forall a. Eq a => NonEmptyVector a -> NonEmptyVector a
NonEmpty.uniq (NonEmptyVector a -> NonEmptyVector a)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> NonEmptyVector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector
  where
    trim :: NonEmptyVector a -> NonEmptyVector a
trim NonEmptyVector a
v
      | NonEmptyVector a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
Foldable.length NonEmptyVector a
v Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 Bool -> Bool -> Bool
|| NonEmptyVector a -> a
forall a. NonEmptyVector a -> a
NonEmpty.head NonEmptyVector a
v a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= NonEmptyVector a -> a
forall a. NonEmptyVector a -> a
NonEmpty.last NonEmptyVector a
v
        = NonEmptyVector a
v
      | Bool
otherwise
        = NonEmptyVector a -> NonEmptyVector a
trim (Vector a -> NonEmptyVector a
forall a. Vector a -> NonEmptyVector a
NonEmpty.unsafeFromVector (Vector a -> NonEmptyVector a) -> Vector a -> NonEmptyVector a
forall a b. (a -> b) -> a -> b
$ NonEmptyVector a -> Vector a
forall a. NonEmptyVector a -> Vector a
NonEmpty.init NonEmptyVector 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 [1..3])
-- [1,3]
mapMaybe
    :: (a -> Maybe b)
    -> CircularVector a
    -> Vector b
mapMaybe :: (a -> Maybe b) -> CircularVector a -> Vector b
mapMaybe a -> Maybe b
f = (a -> Maybe b) -> NonEmptyVector a -> Vector b
forall a b. (a -> Maybe b) -> NonEmptyVector a -> Vector b
NonEmpty.mapMaybe a -> Maybe b
f (NonEmptyVector a -> Vector b)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> Vector b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 [1..3])
-- [1]
--
imapMaybe
    :: (Int -> a -> Maybe b)
    -> CircularVector a
    -> Vector b
imapMaybe :: (Int -> a -> Maybe b) -> CircularVector a -> Vector b
imapMaybe Int -> a -> Maybe b
f = (Int -> a -> Maybe b) -> NonEmptyVector a -> Vector b
forall a b. (Int -> a -> Maybe b) -> NonEmptyVector a -> Vector b
NonEmpty.imapMaybe Int -> a -> Maybe b
f (NonEmptyVector a -> Vector b)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> Vector b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 [1..3])
-- [1,2]
--
takeWhile :: (a -> Bool) -> CircularVector a -> Vector a
takeWhile :: (a -> Bool) -> CircularVector a -> Vector a
takeWhile a -> Bool
f = (a -> Bool) -> NonEmptyVector a -> Vector a
forall a. (a -> Bool) -> NonEmptyVector a -> Vector a
NonEmpty.takeWhile a -> Bool
f (NonEmptyVector a -> Vector a)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 [1..3])
-- [3]
--
dropWhile :: (a -> Bool) -> CircularVector a -> Vector a
dropWhile :: (a -> Bool) -> CircularVector a -> Vector a
dropWhile a -> Bool
f = (a -> Bool) -> NonEmptyVector a -> Vector a
forall a. (a -> Bool) -> NonEmptyVector a -> Vector a
NonEmpty.dropWhile a -> Bool
f (NonEmptyVector a -> Vector a)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 [1..5])
-- ([1,2],[3,4,5])
--
partition :: (a -> Bool) -> CircularVector a -> (Vector a, Vector a)
partition :: (a -> Bool) -> CircularVector a -> (Vector a, Vector a)
partition a -> Bool
f = (a -> Bool) -> NonEmptyVector a -> (Vector a, Vector a)
forall a. (a -> Bool) -> NonEmptyVector a -> (Vector a, Vector a)
NonEmpty.partition a -> Bool
f (NonEmptyVector a -> (Vector a, Vector a))
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> (Vector a, Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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
    :: (a -> Bool)
    -> CircularVector a
    -> (Vector a, Vector a)
unstablePartition :: (a -> Bool) -> CircularVector a -> (Vector a, Vector a)
unstablePartition a -> Bool
f = (a -> Bool) -> NonEmptyVector a -> (Vector a, Vector a)
forall a. (a -> Bool) -> NonEmptyVector a -> (Vector a, Vector a)
NonEmpty.unstablePartition a -> Bool
f (NonEmptyVector a -> (Vector a, Vector a))
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> (Vector a, Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 [1,1,2,3,1])
-- ([1,1],[2,3,1])
--
span :: (a -> Bool) -> CircularVector a -> (Vector a, Vector a)
span :: (a -> Bool) -> CircularVector a -> (Vector a, Vector a)
span a -> Bool
f = (a -> Bool) -> NonEmptyVector a -> (Vector a, Vector a)
forall a. (a -> Bool) -> NonEmptyVector a -> (Vector a, Vector a)
NonEmpty.span a -> Bool
f (NonEmptyVector a -> (Vector a, Vector a))
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> (Vector a, Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 [1,1,2,3,1])
-- ([1,1],[2,3,1])
--
break :: (a -> Bool) -> CircularVector a -> (Vector a, Vector a)
break :: (a -> Bool) -> CircularVector a -> (Vector a, Vector a)
break a -> Bool
f = (a -> Bool) -> NonEmptyVector a -> (Vector a, Vector a)
forall a. (a -> Bool) -> NonEmptyVector a -> (Vector a, Vector a)
NonEmpty.break a -> Bool
f (NonEmptyVector a -> (Vector a, Vector a))
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> (Vector a, Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

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

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

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

-- | /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 [1..3]
-- Just 0
--
-- >>> findIndex (< 0) $ unsafeFromList [1..3]
-- Nothing
--
-- >>> findIndex (==1) $ rotateRight 1 (unsafeFromList [1..3])
-- Just 2
findIndex :: (a -> Bool) -> CircularVector a -> Maybe Int
findIndex :: (a -> Bool) -> CircularVector a -> Maybe Int
findIndex a -> Bool
f = (a -> Bool) -> NonEmptyVector a -> Maybe Int
forall a. (a -> Bool) -> NonEmptyVector a -> Maybe Int
NonEmpty.findIndex a -> Bool
f (NonEmptyVector a -> Maybe Int)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

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

-- | /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 [1..3]
-- Just 0
--
-- >>> elemIndex 0 $ unsafeFromList [1..3]
-- Nothing
--
elemIndex :: Eq a => a -> CircularVector a -> Maybe Int
elemIndex :: a -> CircularVector a -> Maybe Int
elemIndex a
a = a -> NonEmptyVector a -> Maybe Int
forall a. Eq a => a -> NonEmptyVector a -> Maybe Int
NonEmpty.elemIndex a
a (NonEmptyVector a -> Maybe Int)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 [1,2,3,1]
-- [0,3]
--
-- >>> elemIndices 0 $ unsafeFromList [1..3]
-- []
--
elemIndices :: Eq a => a -> CircularVector a -> Vector Int
elemIndices :: a -> CircularVector a -> Vector Int
elemIndices a
a = a -> NonEmptyVector a -> Vector Int
forall a. Eq a => a -> NonEmptyVector a -> Vector Int
NonEmpty.elemIndices a
a (NonEmptyVector a -> Vector Int)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> Vector Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 [1..3])
-- [1,3]
--
-- >>> filter (const False) (unsafeFromList [1..3])
-- []
--
filter :: (a -> Bool) -> CircularVector a -> Vector a
filter :: (a -> Bool) -> CircularVector a -> Vector a
filter a -> Bool
f = (a -> Bool) -> NonEmptyVector a -> Vector a
forall a. (a -> Bool) -> NonEmptyVector a -> Vector a
NonEmpty.filter a -> Bool
f (NonEmptyVector a -> Vector a)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 [1..3])
-- [3]
--
-- >>> ifilter (\_ _ -> False) (unsafeFromList [1..3])
-- []
--
ifilter
    :: (Int -> a -> Bool)
    -> CircularVector a
    -> Vector a
ifilter :: (Int -> a -> Bool) -> CircularVector a -> Vector a
ifilter Int -> a -> Bool
f = (Int -> a -> Bool) -> NonEmptyVector a -> Vector a
forall a. (Int -> a -> Bool) -> NonEmptyVector a -> Vector a
NonEmpty.ifilter Int -> a -> Bool
f (NonEmptyVector a -> Vector a)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 [1..3])
-- Just [1,3]
--
-- >>> filterM (\a -> if a == 2 then Nothing else Just True) (unsafeFromList [1..3])
-- Nothing
--
-- >>> filterM (const $ Just False) (unsafeFromList [1..3])
-- Just []
--
filterM
    :: Monad m
    => (a -> m Bool)
    -> CircularVector a
    -> m (Vector a)
filterM :: (a -> m Bool) -> CircularVector a -> m (Vector a)
filterM a -> m Bool
f = (a -> m Bool) -> NonEmptyVector a -> m (Vector a)
forall (m :: * -> *) a.
Monad m =>
(a -> m Bool) -> NonEmptyVector a -> m (Vector a)
NonEmpty.filterM a -> m Bool
f (NonEmptyVector a -> m (Vector a))
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> m (Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 [1..3])
-- Just [3]
--
-- >>> ifilterM (\i a -> if a == 2 || i == 0 then Nothing else Just True) (unsafeFromList [1..3])
-- Nothing
--
-- >>> ifilterM (\_ _ -> Just False) (unsafeFromList [1..3])
-- Just []
--
ifilterM
    :: Monad m
    => (Int -> a -> m Bool)
    -> CircularVector a
    -> m (Vector a)
ifilterM :: (Int -> a -> m Bool) -> CircularVector a -> m (Vector a)
ifilterM Int -> a -> m Bool
f = (Int -> a -> m Bool) -> NonEmptyVector a -> m (Vector a)
forall (m :: * -> *) a.
Monad m =>
(Int -> a -> m Bool) -> NonEmptyVector a -> m (Vector a)
NonEmpty.ifilterM Int -> a -> m Bool
f (NonEmptyVector a -> m (Vector a))
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> m (Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector

-- | /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 (unsafeFromList [1..3]) (unsafeFromList [2,0])
-- [3,1]
--
backpermute :: CircularVector a -> CircularVector Int -> CircularVector a
backpermute :: CircularVector a -> CircularVector Int -> CircularVector a
backpermute CircularVector a
v CircularVector Int
i = NonEmptyVector a -> CircularVector a
forall a. NonEmptyVector a -> CircularVector a
fromVector (NonEmptyVector a -> CircularVector a)
-> NonEmptyVector a -> CircularVector a
forall a b. (a -> b) -> a -> b
$ NonEmptyVector a -> NonEmptyVector Int -> NonEmptyVector a
forall a.
NonEmptyVector a -> NonEmptyVector Int -> NonEmptyVector a
NonEmpty.backpermute (CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector a
v) (CircularVector Int -> NonEmptyVector Int
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector Int
i)

-- | Same as 'backpermute' but without bounds checking.
--
--   @since 0.1.2
unsafeBackpermute
    :: CircularVector a
    -> CircularVector Int
    -> CircularVector a
unsafeBackpermute :: CircularVector a -> CircularVector Int -> CircularVector a
unsafeBackpermute CircularVector a
v CircularVector Int
i = NonEmptyVector a -> CircularVector a
forall a. NonEmptyVector a -> CircularVector a
fromVector (NonEmptyVector a -> NonEmptyVector Int -> NonEmptyVector a
forall a.
NonEmptyVector a -> NonEmptyVector Int -> NonEmptyVector a
NonEmpty.unsafeBackpermute (CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector a
v) (CircularVector Int -> NonEmptyVector Int
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector CircularVector 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
    :: (forall s. MVector.MVector s a -> ST s ())
    -> CircularVector a
    -> CircularVector a
modify :: (forall s. MVector s a -> ST s ())
-> CircularVector a -> CircularVector a
modify forall s. MVector s a -> ST s ()
p = NonEmptyVector a -> CircularVector a
forall a. NonEmptyVector a -> CircularVector a
fromVector (NonEmptyVector a -> CircularVector a)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> CircularVector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall s. MVector s a -> ST s ())
-> NonEmptyVector a -> NonEmptyVector a
forall a.
(forall s. MVector s a -> ST s ())
-> NonEmptyVector a -> NonEmptyVector a
NonEmpty.modify forall s. MVector s a -> ST s ()
p (NonEmptyVector a -> NonEmptyVector a)
-> (CircularVector a -> NonEmptyVector a)
-> CircularVector a
-> NonEmptyVector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CircularVector a -> NonEmptyVector a
forall a. CircularVector a -> NonEmptyVector a
toNonEmptyVector