    -- |
    -- Module: Optics.Cons.Core
    -- Description: Optics to access the left or right element of a container.
    --
    -- This module defines the 'Cons' and 'Snoc' classes, which provide 'Prism's for
    -- the leftmost and rightmost elements of a container, respectively.
    --
    -- Note that orphan instances for these classes are defined in the @Optics.Cons@
    -- module from @optics-extra@, so if you are not simply depending on @optics@
    -- you may wish to import that module instead.
    --
    module Optics.Cons.Core
      (
      -- * Cons
        Cons(..)
      , (<|)
      , cons
      , uncons
      , _head, _tail
      , pattern (:<)
      -- * Snoc
      , Snoc(..)
      , (|>)
      , snoc
      , unsnoc
      , _init, _last
      , pattern (:>)
      ) where

    import Control.Applicative (ZipList(..))
    import Data.Coerce
    import Data.Sequence hiding ((<|), (|>), (:<), (:>))
    import qualified Data.Sequence as Seq

    import Data.Tuple.Optics
    import Optics.AffineFold
    import Optics.AffineTraversal
    import Optics.Coerce
    import Optics.Internal.Utils
    import Optics.Optic
    import Optics.Prism
    import Optics.Review

    infixr 5 <|, `cons`
    infixl 5 |>, `snoc`

    -- | Pattern synonym for matching on the leftmost element of a structure.
    --
    -- >>> case ['a','b','c'] of (x :< _) -> x
    -- 'a'
    --
    pattern (:<) :: forall s a. Cons s s a a => a -> s -> s
    pattern $m:< :: forall {r} {s} {a}.
    Cons s s a a =>
    s -> (a -> s -> r) -> ((# #) -> r) -> r
    $b:< :: forall s a. Cons s s a a => a -> s -> s
    (:<) a s <- (preview _Cons -> Just (a, s)) where
      (:<) a
    a s
    s = Optic' A_Prism NoIx s (a, s) -> (a, s) -> s
    forall k (is :: IxList) t b.
    Is k A_Review =>
    Optic' k is t b -> b -> t
    review Optic' A_Prism NoIx s (a, s)
    forall s t a b. Cons s t a b => Prism s t (a, s) (b, t)
    _Cons (a
    a, s
    s)

    infixr 5 :<
    infixl 5 :>

    -- | Pattern synonym for matching on the rightmost element of a structure.
    --
    -- >>> case ['a','b','c'] of (_ :> x) -> x
    -- 'c'
    --
    pattern (:>) :: forall s a. Snoc s s a a => s -> a -> s
    pattern $m:> :: forall {r} {s} {a}.
    Snoc s s a a =>
    s -> (s -> a -> r) -> ((# #) -> r) -> r
    $b:> :: forall s a. Snoc s s a a => s -> a -> s
    (:>) s a <- (preview _Snoc -> Just (s, a)) where
      (:>) s
    a a
    s = Optic' A_Prism NoIx s (s, a) -> (s, a) -> s
    forall k (is :: IxList) t b.
    Is k A_Review =>
    Optic' k is t b -> b -> t
    review Optic' A_Prism NoIx s (s, a)
    forall s t a b. Snoc s t a b => Prism s t (s, a) (t, b)
    _Snoc (s
    a, a
    s)

    ------------------------------------------------------------------------------
    -- Cons
    ------------------------------------------------------------------------------

    -- | This class provides a way to attach or detach elements on the left
    -- side of a structure in a flexible manner.
    class Cons s t a b | s -> a, t -> b, s b -> t, t a -> s where
      -- |
      --
      -- @
      -- '_Cons' :: 'Prism' [a] [b] (a, [a]) (b, [b])
      -- '_Cons' :: 'Prism' ('Seq' a) ('Seq' b) (a, 'Seq' a) (b, 'Seq' b)
      -- '_Cons' :: 'Prism' (Vector a) (Vector b) (a, Vector a) (b, Vector b)
      -- '_Cons' :: 'Prism'' 'String' ('Char', 'String')
      -- '_Cons' :: 'Prism'' Text ('Char', Text)
      -- '_Cons' :: 'Prism'' ByteString ('Data.Word.Word8', ByteString)
      -- @
      _Cons :: Prism s t (a, s) (b, t)

    instance Cons [a] [b] a b where
      _Cons :: Prism [a] [b] (a, [a]) (b, [b])
    _Cons = ((b, [b]) -> [b])
    -> ([a] -> Either [b] (a, [a])) -> Prism [a] [b] (a, [a]) (b, [b])
    forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
    prism ((b -> [b] -> [b]) -> (b, [b]) -> [b]
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry' (:)) (([a] -> Either [b] (a, [a])) -> Prism [a] [b] (a, [a]) (b, [b]))
    -> ([a] -> Either [b] (a, [a])) -> Prism [a] [b] (a, [a]) (b, [b])
    forall a b. (a -> b) -> a -> b
    $ \[a]
    aas -> case [a]
    aas of
        (a
    a:[a]
    as) -> (a, [a]) -> Either [b] (a, [a])
    forall a b. b -> Either a b
    Right (a
    a, [a]
    as)
        []     -> [b] -> Either [b] (a, [a])
    forall a b. a -> Either a b
    Left  []
      {-# INLINE _Cons #-}

    instance Cons (ZipList a) (ZipList b) a b where
      _Cons :: Prism (ZipList a) (ZipList b) (a, ZipList a) (b, ZipList b)
    _Cons = Optic A_Prism NoIx [a] (ZipList b) (a, ZipList a) (b, ZipList b)
    -> Prism (ZipList a) (ZipList b) (a, ZipList a) (b, ZipList b)
    forall s s' k (is :: IxList) t a b.
    Coercible s s' =>
    Optic k is s t a b -> Optic k is s' t a b
    coerceS (Optic A_Prism NoIx [a] (ZipList b) (a, ZipList a) (b, ZipList b)
     -> Prism (ZipList a) (ZipList b) (a, ZipList a) (b, ZipList b))
    -> (Prism [a] [b] (a, [a]) (b, [b])
        -> Optic
             A_Prism NoIx [a] (ZipList b) (a, ZipList a) (b, ZipList b))
    -> Prism [a] [b] (a, [a]) (b, [b])
    -> Prism (ZipList a) (ZipList b) (a, ZipList a) (b, ZipList b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Optic A_Prism NoIx [a] [b] (a, ZipList a) (b, ZipList b)
    -> Optic A_Prism NoIx [a] (ZipList b) (a, ZipList a) (b, ZipList b)
    forall t t' k (is :: IxList) s a b.
    Coercible t t' =>
    Optic k is s t a b -> Optic k is s t' a b
    coerceT (Optic A_Prism NoIx [a] [b] (a, ZipList a) (b, ZipList b)
     -> Optic
          A_Prism NoIx [a] (ZipList b) (a, ZipList a) (b, ZipList b))
    -> (Prism [a] [b] (a, [a]) (b, [b])
        -> Optic A_Prism NoIx [a] [b] (a, ZipList a) (b, ZipList b))
    -> Prism [a] [b] (a, [a]) (b, [b])
    -> Optic A_Prism NoIx [a] (ZipList b) (a, ZipList a) (b, ZipList b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Optic A_Prism NoIx [a] [b] (a, [a]) (b, ZipList b)
    -> Optic A_Prism NoIx [a] [b] (a, ZipList a) (b, ZipList b)
    forall a a' k (is :: IxList) s t b.
    Coercible a a' =>
    Optic k is s t a b -> Optic k is s t a' b
    coerceA (Optic A_Prism NoIx [a] [b] (a, [a]) (b, ZipList b)
     -> Optic A_Prism NoIx [a] [b] (a, ZipList a) (b, ZipList b))
    -> (Prism [a] [b] (a, [a]) (b, [b])
        -> Optic A_Prism NoIx [a] [b] (a, [a]) (b, ZipList b))
    -> Prism [a] [b] (a, [a]) (b, [b])
    -> Optic A_Prism NoIx [a] [b] (a, ZipList a) (b, ZipList b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Prism [a] [b] (a, [a]) (b, [b])
    -> Optic A_Prism NoIx [a] [b] (a, [a]) (b, ZipList b)
    forall b b' k (is :: IxList) s t a.
    Coercible b b' =>
    Optic k is s t a b -> Optic k is s t a b'
    coerceB (Prism [a] [b] (a, [a]) (b, [b])
     -> Prism (ZipList a) (ZipList b) (a, ZipList a) (b, ZipList b))
    -> Prism [a] [b] (a, [a]) (b, [b])
    -> Prism (ZipList a) (ZipList b) (a, ZipList a) (b, ZipList b)
    forall a b. (a -> b) -> a -> b
    $ Prism [a] [b] (a, [a]) (b, [b])
    listCons
        where
          listCons :: Prism [a] [b] (a, [a]) (b, [b])
          listCons :: Prism [a] [b] (a, [a]) (b, [b])
    listCons = Prism [a] [b] (a, [a]) (b, [b])
    forall s t a b. Cons s t a b => Prism s t (a, s) (b, t)
    _Cons

      {-# INLINE _Cons #-}

    instance Cons (Seq a) (Seq b) a b where
      _Cons :: Prism (Seq a) (Seq b) (a, Seq a) (b, Seq b)
    _Cons = ((b, Seq b) -> Seq b)
    -> (Seq a -> Either (Seq b) (a, Seq a))
    -> Prism (Seq a) (Seq b) (a, Seq a) (b, Seq b)
    forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
    prism ((b -> Seq b -> Seq b) -> (b, Seq b) -> Seq b
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry' b -> Seq b -> Seq b
    forall a. a -> Seq a -> Seq a
    (Seq.<|)) ((Seq a -> Either (Seq b) (a, Seq a))
     -> Prism (Seq a) (Seq b) (a, Seq a) (b, Seq b))
    -> (Seq a -> Either (Seq b) (a, Seq a))
    -> Prism (Seq a) (Seq b) (a, Seq a) (b, Seq b)
    forall a b. (a -> b) -> a -> b
    $ \Seq a
    aas -> case Seq a -> ViewL a
    forall a. Seq a -> ViewL a
    viewl Seq a
    aas of
        a
    a Seq.:< Seq a
    as -> (a, Seq a) -> Either (Seq b) (a, Seq a)
    forall a b. b -> Either a b
    Right (a
    a, Seq a
    as)
        ViewL a
    EmptyL  -> Seq b -> Either (Seq b) (a, Seq a)
    forall a b. a -> Either a b
    Left Seq b
    forall a. Monoid a => a
    mempty
      {-# INLINE _Cons #-}

    -- | 'cons' an element onto a container.
    --
    -- This is an infix alias for 'cons'.
    --
    -- >>> 1 <| []
    -- [1]
    --
    -- >>> 'a' <| "bc"
    -- "abc"
    --
    -- >>> 1 <| []
    -- [1]
    --
    -- >>> 1 <| [2, 3]
    -- [1,2,3]
    (<|) :: Cons s s a a => a -> s -> s
    <| :: forall s a. Cons s s a a => a -> s -> s
    (<|) = ((a, s) -> s) -> a -> s -> s
    forall a b c. ((a, b) -> c) -> a -> b -> c
    curry (Optic' A_Prism NoIx s (a, s) -> (a, s) -> s
    forall k (is :: IxList) t b.
    Is k A_Review =>
    Optic' k is t b -> b -> t
    review Optic' A_Prism NoIx s (a, s)
    forall s t a b. Cons s t a b => Prism s t (a, s) (b, t)
    _Cons)
    {-# INLINE (<|) #-}

    -- | 'cons' an element onto a container.
    --
    -- >>> cons 'a' ""
    -- "a"
    --
    -- >>> cons 'a' "bc"
    -- "abc"
    cons :: Cons s s a a => a -> s -> s
    cons :: forall s a. Cons s s a a => a -> s -> s
    cons = ((a, s) -> s) -> a -> s -> s
    forall a b c. ((a, b) -> c) -> a -> b -> c
    curry (Optic' A_Prism NoIx s (a, s) -> (a, s) -> s
    forall k (is :: IxList) t b.
    Is k A_Review =>
    Optic' k is t b -> b -> t
    review Optic' A_Prism NoIx s (a, s)
    forall s t a b. Cons s t a b => Prism s t (a, s) (b, t)
    _Cons)
    {-# INLINE cons #-}

    -- | Attempt to extract the left-most element from a container, and a version of
    -- the container without that element.
    --
    -- >>> uncons []
    -- Nothing
    --
    -- >>> uncons [1, 2, 3]
    -- Just (1,[2,3])
    uncons :: Cons s s a a => s -> Maybe (a, s)
    uncons :: forall s a. Cons s s a a => s -> Maybe (a, s)
    uncons = Optic' A_Prism NoIx s (a, s) -> s -> Maybe (a, s)
    forall k (is :: IxList) s a.
    Is k An_AffineFold =>
    Optic' k is s a -> s -> Maybe a
    preview Optic' A_Prism NoIx s (a, s)
    forall s t a b. Cons s t a b => Prism s t (a, s) (b, t)
    _Cons
    {-# INLINE uncons #-}

    -- | An 'AffineTraversal' reading and writing to the 'head' of a /non-empty/
    -- container.
    --
    -- >>> "abc" ^? _head
    -- Just 'a'
    --
    -- >>> "abc" & _head .~ 'd'
    -- "dbc"
    --
    -- >>> [1,2,3] & _head %~ (*10)
    -- [10,2,3]
    --
    -- >>> [] & _head %~ absurd
    -- []
    --
    -- >>> [1,2,3] ^? _head
    -- Just 1
    --
    -- >>> [] ^? _head
    -- Nothing
    --
    -- >>> [1,2] ^? _head
    -- Just 1
    --
    -- >>> [] & _head .~ 1
    -- []
    --
    -- >>> [0] & _head .~ 2
    -- [2]
    --
    -- >>> [0,1] & _head .~ 2
    -- [2,1]
    _head :: Cons s s a a => AffineTraversal' s a
    _head :: forall s a. Cons s s a a => AffineTraversal' s a
    _head = Prism s s (a, s) (a, s)
    forall s t a b. Cons s t a b => Prism s t (a, s) (b, t)
    _Cons Prism s s (a, s) (a, s)
    -> Optic A_Lens NoIx (a, s) (a, s) a a
    -> Optic An_AffineTraversal NoIx s s a a
    forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
           b.
    (JoinKinds k l m, AppendIndices is js ks) =>
    Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
    % Optic A_Lens NoIx (a, s) (a, s) a a
    forall s t a b. Field1 s t a b => Lens s t a b
    _1
    {-# INLINE _head #-}

    -- | An 'AffineTraversal' reading and writing to the 'tail' of a /non-empty/
    -- container.
    --
    -- >>> "ab" & _tail .~ "cde"
    -- "acde"
    --
    -- >>> [] & _tail .~ [1,2]
    -- []
    --
    -- >>> [1,2,3,4,5] & _tail % traversed %~ (*10)
    -- [1,20,30,40,50]
    --
    -- >>> [1,2] & _tail .~ [3,4,5]
    -- [1,3,4,5]
    --
    -- >>> [] & _tail .~ [1,2]
    -- []
    --
    -- >>> "abc" ^? _tail
    -- Just "bc"
    --
    -- >>> "hello" ^? _tail
    -- Just "ello"
    --
    -- >>> "" ^? _tail
    -- Nothing
    _tail :: Cons s s a a => AffineTraversal' s s
    _tail :: forall s a. Cons s s a a => AffineTraversal' s s
    _tail = Prism s s (a, s) (a, s)
    forall s t a b. Cons s t a b => Prism s t (a, s) (b, t)
    _Cons Prism s s (a, s) (a, s)
    -> Optic A_Lens NoIx (a, s) (a, s) s s
    -> Optic An_AffineTraversal NoIx s s s s
    forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
           b.
    (JoinKinds k l m, AppendIndices is js ks) =>
    Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
    % Optic A_Lens NoIx (a, s) (a, s) s s
    forall s t a b. Field2 s t a b => Lens s t a b
    _2
    {-# INLINE _tail #-}

    ------------------------------------------------------------------------------
    -- Snoc
    ------------------------------------------------------------------------------

    -- | This class provides a way to attach or detach elements on the right side of
    -- a structure in a flexible manner.
    class Snoc s t a b | s -> a, t -> b, s b -> t, t a -> s where
      _Snoc :: Prism s t (s, a) (t, b)

    instance Snoc [a] [b] a b where
      _Snoc :: Prism [a] [b] ([a], a) ([b], b)
    _Snoc = (([b], b) -> [b])
    -> ([a] -> Either [b] ([a], a)) -> Prism [a] [b] ([a], a) ([b], b)
    forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
    prism (\([b]
    as,b
    a) -> [b]
    as [b] -> [b] -> [b]
    forall a. [a] -> [a] -> [a]
    Prelude.++ [b
    a]) (([a] -> Either [b] ([a], a)) -> Prism [a] [b] ([a], a) ([b], b))
    -> ([a] -> Either [b] ([a], a)) -> Prism [a] [b] ([a], a) ([b], b)
    forall a b. (a -> b) -> a -> b
    $ \[a]
    aas -> if [a] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    Prelude.null [a]
    aas
        then [b] -> Either [b] ([a], a)
    forall a b. a -> Either a b
    Left []
        else ([a], a) -> Either [b] ([a], a)
    forall a b. b -> Either a b
    Right ([a] -> [a]
    forall a. HasCallStack => [a] -> [a]
    Prelude.init [a]
    aas, [a] -> a
    forall a. HasCallStack => [a] -> a
    Prelude.last [a]
    aas)
      {-# INLINE _Snoc #-}

    instance Snoc (ZipList a) (ZipList b) a b where
      _Snoc :: Prism (ZipList a) (ZipList b) (ZipList a, a) (ZipList b, b)
    _Snoc = Optic A_Prism NoIx [a] [b] ([a], a) ([b], b)
    -> ((([b], b) -> [b])
        -> ([a] -> Either [b] ([a], a))
        -> Prism (ZipList a) (ZipList b) (ZipList a, a) (ZipList b, b))
    -> Prism (ZipList a) (ZipList b) (ZipList a, a) (ZipList b, b)
    forall k (is :: IxList) s t a b r.
    Is k A_Prism =>
    Optic k is s t a b -> ((b -> t) -> (s -> Either t a) -> r) -> r
    withPrism Optic A_Prism NoIx [a] [b] ([a], a) ([b], b)
    listSnoc (((([b], b) -> [b])
      -> ([a] -> Either [b] ([a], a))
      -> Prism (ZipList a) (ZipList b) (ZipList a, a) (ZipList b, b))
     -> Prism (ZipList a) (ZipList b) (ZipList a, a) (ZipList b, b))
    -> ((([b], b) -> [b])
        -> ([a] -> Either [b] ([a], a))
        -> Prism (ZipList a) (ZipList b) (ZipList a, a) (ZipList b, b))
    -> Prism (ZipList a) (ZipList b) (ZipList a, a) (ZipList b, b)
    forall a b. (a -> b) -> a -> b
    $ \([b], b) -> [b]
    listReview [a] -> Either [b] ([a], a)
    listPreview ->
        ((ZipList b, b) -> ZipList b)
    -> (ZipList a -> Either (ZipList b) (ZipList a, a))
    -> Prism (ZipList a) (ZipList b) (ZipList a, a) (ZipList b, b)
    forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
    prism ((([b], b) -> [b]) -> (ZipList b, b) -> ZipList b
    forall a b. Coercible a b => a -> b
    coerce ([b], b) -> [b]
    listReview) (([a] -> Either [b] ([a], a))
    -> ZipList a -> Either (ZipList b) (ZipList a, a)
    forall a b. Coercible a b => a -> b
    coerce [a] -> Either [b] ([a], a)
    listPreview) where

        listSnoc :: Prism [a] [b] ([a], a) ([b], b)
        listSnoc :: Optic A_Prism NoIx [a] [b] ([a], a) ([b], b)
    listSnoc = Optic A_Prism NoIx [a] [b] ([a], a) ([b], b)
    forall s t a b. Snoc s t a b => Prism s t (s, a) (t, b)
    _Snoc

      {-# INLINE _Snoc #-}

    instance Snoc (Seq a) (Seq b) a b where
      _Snoc :: Prism (Seq a) (Seq b) (Seq a, a) (Seq b, b)
    _Snoc = ((Seq b, b) -> Seq b)
    -> (Seq a -> Either (Seq b) (Seq a, a))
    -> Prism (Seq a) (Seq b) (Seq a, a) (Seq b, b)
    forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
    prism ((Seq b -> b -> Seq b) -> (Seq b, b) -> Seq b
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry' Seq b -> b -> Seq b
    forall a. Seq a -> a -> Seq a
    (Seq.|>)) ((Seq a -> Either (Seq b) (Seq a, a))
     -> Prism (Seq a) (Seq b) (Seq a, a) (Seq b, b))
    -> (Seq a -> Either (Seq b) (Seq a, a))
    -> Prism (Seq a) (Seq b) (Seq a, a) (Seq b, b)
    forall a b. (a -> b) -> a -> b
    $ \Seq a
    aas -> case Seq a -> ViewR a
    forall a. Seq a -> ViewR a
    viewr Seq a
    aas of
        Seq a
    as Seq.:> a
    a -> (Seq a, a) -> Either (Seq b) (Seq a, a)
    forall a b. b -> Either a b
    Right (Seq a
    as, a
    a)
        ViewR a
    EmptyR  -> Seq b -> Either (Seq b) (Seq a, a)
    forall a b. a -> Either a b
    Left Seq b
    forall a. Monoid a => a
    mempty
      {-# INLINE _Snoc #-}

    -- | An 'AffineTraversal' reading and replacing all but the a last element of a
    -- /non-empty/ container.
    --
    -- >>> "abcd" ^? _init
    -- Just "abc"
    --
    -- >>> "" ^? _init
    -- Nothing
    --
    -- >>> "ab" & _init .~ "cde"
    -- "cdeb"
    --
    -- >>> [] & _init .~ [1,2]
    -- []
    --
    -- >>> [1,2,3,4] & _init % traversed %~ (*10)
    -- [10,20,30,4]
    --
    -- >>> [1,2,3] ^? _init
    -- Just [1,2]
    --
    -- >>> "hello" ^? _init
    -- Just "hell"
    --
    -- >>> [] ^? _init
    -- Nothing
    _init :: Snoc s s a a => AffineTraversal' s s
    _init :: forall s a. Snoc s s a a => AffineTraversal' s s
    _init = Prism s s (s, a) (s, a)
    forall s t a b. Snoc s t a b => Prism s t (s, a) (t, b)
    _Snoc Prism s s (s, a) (s, a)
    -> Optic A_Lens NoIx (s, a) (s, a) s s
    -> Optic An_AffineTraversal NoIx s s s s
    forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
           b.
    (JoinKinds k l m, AppendIndices is js ks) =>
    Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
    % Optic A_Lens NoIx (s, a) (s, a) s s
    forall s t a b. Field1 s t a b => Lens s t a b
    _1
    {-# INLINE _init #-}

    -- | An 'AffineTraversal' reading and writing to the last element of a
    -- /non-empty/ container.
    --
    -- >>> "abc" ^? _last
    -- Just 'c'
    --
    -- >>> "" ^? _last
    -- Nothing
    --
    -- >>> [1,2,3] & _last %~ (+1)
    -- [1,2,4]
    --
    -- >>> [1,2] ^? _last
    -- Just 2
    --
    -- >>> [] & _last .~ 1
    -- []
    --
    -- >>> [0] & _last .~ 2
    -- [2]
    --
    -- >>> [0,1] & _last .~ 2
    -- [0,2]
    _last :: Snoc s s a a => AffineTraversal' s a
    _last :: forall s a. Snoc s s a a => AffineTraversal' s a
    _last = Prism s s (s, a) (s, a)
    forall s t a b. Snoc s t a b => Prism s t (s, a) (t, b)
    _Snoc Prism s s (s, a) (s, a)
    -> Optic A_Lens NoIx (s, a) (s, a) a a
    -> Optic An_AffineTraversal NoIx s s a a
    forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
           b.
    (JoinKinds k l m, AppendIndices is js ks) =>
    Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
    % Optic A_Lens NoIx (s, a) (s, a) a a
    forall s t a b. Field2 s t a b => Lens s t a b
    _2
    {-# INLINE _last #-}

    -- | 'snoc' an element onto the end of a container.
    --
    -- This is an infix alias for 'snoc'.
    --
    -- >>> "" |> 'a'
    -- "a"
    --
    -- >>> "bc" |> 'a'
    -- "bca"
    (|>) :: Snoc s s a a => s -> a -> s
    |> :: forall s a. Snoc s s a a => s -> a -> s
    (|>) = ((s, a) -> s) -> s -> a -> s
    forall a b c. ((a, b) -> c) -> a -> b -> c
    curry (Optic' A_Prism NoIx s (s, a) -> (s, a) -> s
    forall k (is :: IxList) t b.
    Is k A_Review =>
    Optic' k is t b -> b -> t
    review Optic' A_Prism NoIx s (s, a)
    forall s t a b. Snoc s t a b => Prism s t (s, a) (t, b)
    _Snoc)
    {-# INLINE (|>) #-}

    -- | 'snoc' an element onto the end of a container.
    --
    -- >>> snoc "hello" '!'
    -- "hello!"
    snoc  :: Snoc s s a a => s -> a -> s
    snoc :: forall s a. Snoc s s a a => s -> a -> s
    snoc = ((s, a) -> s) -> s -> a -> s
    forall a b c. ((a, b) -> c) -> a -> b -> c
    curry (Optic' A_Prism NoIx s (s, a) -> (s, a) -> s
    forall k (is :: IxList) t b.
    Is k A_Review =>
    Optic' k is t b -> b -> t
    review Optic' A_Prism NoIx s (s, a)
    forall s t a b. Snoc s t a b => Prism s t (s, a) (t, b)
    _Snoc)
    {-# INLINE snoc #-}

    -- | Attempt to extract the right-most element from a container, and a version
    -- of the container without that element.
    --
    -- >>> unsnoc "hello!"
    -- Just ("hello",'!')
    --
    -- >>> unsnoc ""
    -- Nothing
    unsnoc :: Snoc s s a a => s -> Maybe (s, a)
    unsnoc :: forall s a. Snoc s s a a => s -> Maybe (s, a)
    unsnoc s
    s = Optic' A_Prism NoIx s (s, a) -> s -> Maybe (s, a)
    forall k (is :: IxList) s a.
    Is k An_AffineFold =>
    Optic' k is s a -> s -> Maybe a
    preview Optic' A_Prism NoIx s (s, a)
    forall s t a b. Snoc s t a b => Prism s t (s, a) (t, b)
    _Snoc s
    s
    {-# INLINE unsnoc #-}

    -- $setup
    -- >>> import Data.Void
    -- >>> import Optics.Core