{-|
Module      : Data.Profunctor.Separator
Description : separators
Copyright   : (C) 2026 - Eitan Chatav
License     : BSD-style (see the file LICENSE)
Maintainer  : Eitan Chatav <eitan.chatav@gmail.com>
Stability   : provisional
Portability : non-portable
-}

module Data.Profunctor.Separator
  ( -- * SepBy
    SepBy (..)
  , sepBy
  , noSep
  , sepWith
  , beginWith
  , endWith
    -- * SepBy Combinators
  , several
  , several1
  , chain
  , chain1
  , intercalateP
  ) where

import Control.Lens
import Control.Lens.PartialIso
import Control.Lens.Grammar.Symbol
import Data.Profunctor.Distributor
import Data.Profunctor.Monoidal
import GHC.Exts

{- | Used to sequence multiple times,
separated by a `separateBy`,
begun by a `beginBy`,
and ended by an `endBy`. -}
data SepBy p = SepBy
  { forall p. SepBy p -> p
beginBy :: p
  , forall p. SepBy p -> p
endBy :: p
  , forall p. SepBy p -> p
separateBy :: p
  } deriving stock
    ( (forall a b. (a -> b) -> SepBy a -> SepBy b)
-> (forall a b. a -> SepBy b -> SepBy a) -> Functor SepBy
forall a b. a -> SepBy b -> SepBy a
forall a b. (a -> b) -> SepBy a -> SepBy b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> SepBy a -> SepBy b
fmap :: forall a b. (a -> b) -> SepBy a -> SepBy b
$c<$ :: forall a b. a -> SepBy b -> SepBy a
<$ :: forall a b. a -> SepBy b -> SepBy a
Functor, (forall m. Monoid m => SepBy m -> m)
-> (forall m a. Monoid m => (a -> m) -> SepBy a -> m)
-> (forall m a. Monoid m => (a -> m) -> SepBy a -> m)
-> (forall a b. (a -> b -> b) -> b -> SepBy a -> b)
-> (forall a b. (a -> b -> b) -> b -> SepBy a -> b)
-> (forall b a. (b -> a -> b) -> b -> SepBy a -> b)
-> (forall b a. (b -> a -> b) -> b -> SepBy a -> b)
-> (forall a. (a -> a -> a) -> SepBy a -> a)
-> (forall a. (a -> a -> a) -> SepBy a -> a)
-> (forall a. SepBy a -> [a])
-> (forall a. SepBy a -> Bool)
-> (forall a. SepBy a -> Int)
-> (forall a. Eq a => a -> SepBy a -> Bool)
-> (forall a. Ord a => SepBy a -> a)
-> (forall a. Ord a => SepBy a -> a)
-> (forall a. Num a => SepBy a -> a)
-> (forall a. Num a => SepBy a -> a)
-> Foldable SepBy
forall a. Eq a => a -> SepBy a -> Bool
forall a. Num a => SepBy a -> a
forall a. Ord a => SepBy a -> a
forall m. Monoid m => SepBy m -> m
forall a. SepBy a -> Bool
forall a. SepBy a -> Int
forall a. SepBy a -> [a]
forall a. (a -> a -> a) -> SepBy a -> a
forall m a. Monoid m => (a -> m) -> SepBy a -> m
forall b a. (b -> a -> b) -> b -> SepBy a -> b
forall a b. (a -> b -> b) -> b -> SepBy a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => SepBy m -> m
fold :: forall m. Monoid m => SepBy m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> SepBy a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> SepBy a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> SepBy a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> SepBy a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> SepBy a -> b
foldr :: forall a b. (a -> b -> b) -> b -> SepBy a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> SepBy a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> SepBy a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> SepBy a -> b
foldl :: forall b a. (b -> a -> b) -> b -> SepBy a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> SepBy a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> SepBy a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> SepBy a -> a
foldr1 :: forall a. (a -> a -> a) -> SepBy a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> SepBy a -> a
foldl1 :: forall a. (a -> a -> a) -> SepBy a -> a
$ctoList :: forall a. SepBy a -> [a]
toList :: forall a. SepBy a -> [a]
$cnull :: forall a. SepBy a -> Bool
null :: forall a. SepBy a -> Bool
$clength :: forall a. SepBy a -> Int
length :: forall a. SepBy a -> Int
$celem :: forall a. Eq a => a -> SepBy a -> Bool
elem :: forall a. Eq a => a -> SepBy a -> Bool
$cmaximum :: forall a. Ord a => SepBy a -> a
maximum :: forall a. Ord a => SepBy a -> a
$cminimum :: forall a. Ord a => SepBy a -> a
minimum :: forall a. Ord a => SepBy a -> a
$csum :: forall a. Num a => SepBy a -> a
sum :: forall a. Num a => SepBy a -> a
$cproduct :: forall a. Num a => SepBy a -> a
product :: forall a. Num a => SepBy a -> a
Foldable, Functor SepBy
Foldable SepBy
(Functor SepBy, Foldable SepBy) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> SepBy a -> f (SepBy b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    SepBy (f a) -> f (SepBy a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> SepBy a -> m (SepBy b))
-> (forall (m :: * -> *) a. Monad m => SepBy (m a) -> m (SepBy a))
-> Traversable SepBy
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => SepBy (m a) -> m (SepBy a)
forall (f :: * -> *) a. Applicative f => SepBy (f a) -> f (SepBy a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> SepBy a -> m (SepBy b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> SepBy a -> f (SepBy b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> SepBy a -> f (SepBy b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> SepBy a -> f (SepBy b)
$csequenceA :: forall (f :: * -> *) a. Applicative f => SepBy (f a) -> f (SepBy a)
sequenceA :: forall (f :: * -> *) a. Applicative f => SepBy (f a) -> f (SepBy a)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> SepBy a -> m (SepBy b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> SepBy a -> m (SepBy b)
$csequence :: forall (m :: * -> *) a. Monad m => SepBy (m a) -> m (SepBy a)
sequence :: forall (m :: * -> *) a. Monad m => SepBy (m a) -> m (SepBy a)
Traversable
    , SepBy p -> SepBy p -> Bool
(SepBy p -> SepBy p -> Bool)
-> (SepBy p -> SepBy p -> Bool) -> Eq (SepBy p)
forall p. Eq p => SepBy p -> SepBy p -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall p. Eq p => SepBy p -> SepBy p -> Bool
== :: SepBy p -> SepBy p -> Bool
$c/= :: forall p. Eq p => SepBy p -> SepBy p -> Bool
/= :: SepBy p -> SepBy p -> Bool
Eq, Eq (SepBy p)
Eq (SepBy p) =>
(SepBy p -> SepBy p -> Ordering)
-> (SepBy p -> SepBy p -> Bool)
-> (SepBy p -> SepBy p -> Bool)
-> (SepBy p -> SepBy p -> Bool)
-> (SepBy p -> SepBy p -> Bool)
-> (SepBy p -> SepBy p -> SepBy p)
-> (SepBy p -> SepBy p -> SepBy p)
-> Ord (SepBy p)
SepBy p -> SepBy p -> Bool
SepBy p -> SepBy p -> Ordering
SepBy p -> SepBy p -> SepBy p
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall p. Ord p => Eq (SepBy p)
forall p. Ord p => SepBy p -> SepBy p -> Bool
forall p. Ord p => SepBy p -> SepBy p -> Ordering
forall p. Ord p => SepBy p -> SepBy p -> SepBy p
$ccompare :: forall p. Ord p => SepBy p -> SepBy p -> Ordering
compare :: SepBy p -> SepBy p -> Ordering
$c< :: forall p. Ord p => SepBy p -> SepBy p -> Bool
< :: SepBy p -> SepBy p -> Bool
$c<= :: forall p. Ord p => SepBy p -> SepBy p -> Bool
<= :: SepBy p -> SepBy p -> Bool
$c> :: forall p. Ord p => SepBy p -> SepBy p -> Bool
> :: SepBy p -> SepBy p -> Bool
$c>= :: forall p. Ord p => SepBy p -> SepBy p -> Bool
>= :: SepBy p -> SepBy p -> Bool
$cmax :: forall p. Ord p => SepBy p -> SepBy p -> SepBy p
max :: SepBy p -> SepBy p -> SepBy p
$cmin :: forall p. Ord p => SepBy p -> SepBy p -> SepBy p
min :: SepBy p -> SepBy p -> SepBy p
Ord, Int -> SepBy p -> ShowS
[SepBy p] -> ShowS
SepBy p -> String
(Int -> SepBy p -> ShowS)
-> (SepBy p -> String) -> ([SepBy p] -> ShowS) -> Show (SepBy p)
forall p. Show p => Int -> SepBy p -> ShowS
forall p. Show p => [SepBy p] -> ShowS
forall p. Show p => SepBy p -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall p. Show p => Int -> SepBy p -> ShowS
showsPrec :: Int -> SepBy p -> ShowS
$cshow :: forall p. Show p => SepBy p -> String
show :: SepBy p -> String
$cshowList :: forall p. Show p => [SepBy p] -> ShowS
showList :: [SepBy p] -> ShowS
Show, ReadPrec [SepBy p]
ReadPrec (SepBy p)
Int -> ReadS (SepBy p)
ReadS [SepBy p]
(Int -> ReadS (SepBy p))
-> ReadS [SepBy p]
-> ReadPrec (SepBy p)
-> ReadPrec [SepBy p]
-> Read (SepBy p)
forall p. Read p => ReadPrec [SepBy p]
forall p. Read p => ReadPrec (SepBy p)
forall p. Read p => Int -> ReadS (SepBy p)
forall p. Read p => ReadS [SepBy p]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall p. Read p => Int -> ReadS (SepBy p)
readsPrec :: Int -> ReadS (SepBy p)
$creadList :: forall p. Read p => ReadS [SepBy p]
readList :: ReadS [SepBy p]
$creadPrec :: forall p. Read p => ReadPrec (SepBy p)
readPrec :: ReadPrec (SepBy p)
$creadListPrec :: forall p. Read p => ReadPrec [SepBy p]
readListPrec :: ReadPrec [SepBy p]
Read
    )

{- | A `SepBy` smart constructor,
setting the `separateBy` field.
Beginning and ending delimitors will be no-ops,
except by modifier record updates `beginBy` or `endBy`. -}
sepBy :: Applicative p => p () -> SepBy (p ())
sepBy :: forall (p :: * -> *). Applicative p => p () -> SepBy (p ())
sepBy = p () -> p () -> p () -> SepBy (p ())
forall p. p -> p -> p -> SepBy p
SepBy (() -> p ()
forall a. a -> p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) (() -> p ()
forall a. a -> p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())

{- | A `SepBy` smart constructor for no separator,
beginning or ending delimiters. -}
noSep :: Applicative p => SepBy (p ())
noSep :: forall (p :: * -> *). Applicative p => SepBy (p ())
noSep = p () -> SepBy (p ())
forall (p :: * -> *). Applicative p => p () -> SepBy (p ())
sepBy (() -> p ()
forall a. a -> p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())

{- | A `SepBy` smart constructor like `sepBy`,
with a `terminal` argument.
Beginning and ending delimitors will be no-ops,
except by applying smart modifiers `beginWith` or `endWith`. -}
sepWith
  :: (Applicative p, TerminalSymbol c (p ()))
  => [c] -> SepBy (p ())
sepWith :: forall (p :: * -> *) c.
(Applicative p, TerminalSymbol c (p ())) =>
[c] -> SepBy (p ())
sepWith = p () -> SepBy (p ())
forall (p :: * -> *). Applicative p => p () -> SepBy (p ())
sepBy (p () -> SepBy (p ())) -> ([c] -> p ()) -> [c] -> SepBy (p ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [c] -> p ()
forall token s. TerminalSymbol token s => [token] -> s
terminal

{- | A `SepBy` smart modifier like `beginBy`,
with a `terminal` argument. -}
beginWith :: TerminalSymbol c p => [c] -> SepBy p -> SepBy p
beginWith :: forall c p. TerminalSymbol c p => [c] -> SepBy p -> SepBy p
beginWith [c]
str SepBy p
separator = SepBy p
separator {beginBy = terminal str}

{- | A `SepBy` smart modifier like `endBy`,
with a `terminal` argument. -}
endWith :: TerminalSymbol c p => [c] -> SepBy p -> SepBy p
endWith :: forall c p. TerminalSymbol c p => [c] -> SepBy p -> SepBy p
endWith [c]
str SepBy p
separator = SepBy p
separator {endBy = terminal str}

{- |
prop> several noSep = manyP
-}
several
  :: (IsList s, IsList t, Distributor p)
  => SepBy (p () ()) -> p (Item s) (Item t) -> p s t
several :: forall s t (p :: * -> * -> *).
(IsList s, IsList t, Distributor p) =>
SepBy (p () ()) -> p (Item s) (Item t) -> p s t
several (SepBy p () ()
beg p () ()
end p () ()
sep) p (Item s) (Item t)
p = (s -> [Item s]) -> ([Item t] -> t) -> Iso s t [Item s] [Item t]
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso s -> [Item s]
forall l. IsList l => l -> [Item l]
toList [Item t] -> t
forall l. IsList l => [Item l] -> l
fromList (Exchange
   (Either (Item s, [Item s]) ())
   (Either (Item t, [Item t]) ())
   [Item s]
   (Identity [Item t])
 -> Exchange
      (Either (Item s, [Item s]) ())
      (Either (Item t, [Item t]) ())
      s
      (Identity t))
-> (Exchange
      (Either (Item s, [Item s]) ())
      (Either (Item t, [Item t]) ())
      (Either (Item s, [Item s]) ())
      (Identity (Either (Item t, [Item t]) ()))
    -> Exchange
         (Either (Item s, [Item s]) ())
         (Either (Item t, [Item t]) ())
         [Item s]
         (Identity [Item t]))
-> Exchange
     (Either (Item s, [Item s]) ())
     (Either (Item t, [Item t]) ())
     (Either (Item s, [Item s]) ())
     (Identity (Either (Item t, [Item t]) ()))
-> Exchange
     (Either (Item s, [Item s]) ())
     (Either (Item t, [Item t]) ())
     s
     (Identity t)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Exchange
  (Either (Item s, [Item s]) ())
  (Either (Item t, [Item t]) ())
  (Either (Item s, [Item s]) ())
  (Identity (Either (Item t, [Item t]) ()))
-> Exchange
     (Either (Item s, [Item s]) ())
     (Either (Item t, [Item t]) ())
     [Item s]
     (Identity [Item t])
forall s a t b.
(Cons s s a a, AsEmpty t, Cons t t b b) =>
Iso s t (Either (a, s) ()) (Either (b, t) ())
Iso
  [Item s]
  [Item t]
  (Either (Item s, [Item s]) ())
  (Either (Item t, [Item t]) ())
eotList (Exchange
   (Either (Item s, [Item s]) ())
   (Either (Item t, [Item t]) ())
   (Either (Item s, [Item s]) ())
   (Identity (Either (Item t, [Item t]) ()))
 -> Exchange
      (Either (Item s, [Item s]) ())
      (Either (Item t, [Item t]) ())
      s
      (Identity t))
-> p (Either (Item s, [Item s]) ()) (Either (Item t, [Item t]) ())
-> p s t
forall (p :: * -> * -> *) s t a b.
Profunctor p =>
AnIso s t a b -> p a b -> p s t
>~
  p () ()
beg p () ()
-> p (Either (Item s, [Item s]) ()) (Either (Item t, [Item t]) ())
-> p (Either (Item s, [Item s]) ()) (Either (Item t, [Item t]) ())
forall (p :: * -> * -> *) c a b.
Monoidal p =>
p () c -> p a b -> p a b
>* (p (Item s) (Item t)
p p (Item s) (Item t)
-> p [Item s] [Item t] -> p (Item s, [Item s]) (Item t, [Item t])
forall (p :: * -> * -> *) a b c d.
Monoidal p =>
p a b -> p c d -> p (a, c) (b, d)
>*< p (Item s) (Item t) -> p [Item s] [Item t]
forall a b. p a b -> p [a] [b]
forall (p :: * -> * -> *) a b. Distributor p => p a b -> p [a] [b]
manyP (p () ()
sep p () () -> p (Item s) (Item t) -> p (Item s) (Item t)
forall (p :: * -> * -> *) c a b.
Monoidal p =>
p () c -> p a b -> p a b
>* p (Item s) (Item t)
p) p (Item s, [Item s]) (Item t, [Item t])
-> p () ()
-> p (Either (Item s, [Item s]) ()) (Either (Item t, [Item t]) ())
forall a b c d. p a b -> p c d -> p (Either a c) (Either b d)
forall (p :: * -> * -> *) a b c d.
Distributor p =>
p a b -> p c d -> p (Either a c) (Either b d)
>+< p () ()
forall (p :: * -> * -> *). Monoidal p => p () ()
oneP) p (Either (Item s, [Item s]) ()) (Either (Item t, [Item t]) ())
-> p () ()
-> p (Either (Item s, [Item s]) ()) (Either (Item t, [Item t]) ())
forall (p :: * -> * -> *) a b c.
Monoidal p =>
p a b -> p () c -> p a b
*< p () ()
end

{- |
prop> several1 noSep = someP
-}
several1
  :: (IsList s, IsList t, Distributor p, Choice p)
  => SepBy (p () ()) -> p (Item s) (Item t) -> p s t
several1 :: forall s t (p :: * -> * -> *).
(IsList s, IsList t, Distributor p, Choice p) =>
SepBy (p () ()) -> p (Item s) (Item t) -> p s t
several1 (SepBy p () ()
beg p () ()
end p () ()
sep) p (Item s) (Item t)
p = (s -> [Item s]) -> ([Item t] -> t) -> Iso s t [Item s] [Item t]
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso s -> [Item s]
forall l. IsList l => l -> [Item l]
toList [Item t] -> t
forall l. IsList l => [Item l] -> l
fromList (Market
   (Item s, [Item s]) (Item t, [Item t]) [Item s] (Identity [Item t])
 -> Market (Item s, [Item s]) (Item t, [Item t]) s (Identity t))
-> (Market
      (Item s, [Item s])
      (Item t, [Item t])
      (Item s, [Item s])
      (Identity (Item t, [Item t]))
    -> Market
         (Item s, [Item s]) (Item t, [Item t]) [Item s] (Identity [Item t]))
-> Market
     (Item s, [Item s])
     (Item t, [Item t])
     (Item s, [Item s])
     (Identity (Item t, [Item t]))
-> Market (Item s, [Item s]) (Item t, [Item t]) s (Identity t)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Market
  (Item s, [Item s])
  (Item t, [Item t])
  (Item s, [Item s])
  (Identity (Item t, [Item t]))
-> Market
     (Item s, [Item s]) (Item t, [Item t]) [Item s] (Identity [Item t])
forall s t a b. Cons s t a b => Prism s t (a, s) (b, t)
Prism [Item s] [Item t] (Item s, [Item s]) (Item t, [Item t])
_Cons (Market
   (Item s, [Item s])
   (Item t, [Item t])
   (Item s, [Item s])
   (Identity (Item t, [Item t]))
 -> Market (Item s, [Item s]) (Item t, [Item t]) s (Identity t))
-> p (Item s, [Item s]) (Item t, [Item t]) -> p s t
forall (p :: * -> * -> *) s t a b.
Choice p =>
APrism s t a b -> p a b -> p s t
>?
  p () ()
beg p () ()
-> p (Item s, [Item s]) (Item t, [Item t])
-> p (Item s, [Item s]) (Item t, [Item t])
forall (p :: * -> * -> *) c a b.
Monoidal p =>
p () c -> p a b -> p a b
>* (p (Item s) (Item t)
p p (Item s) (Item t)
-> p [Item s] [Item t] -> p (Item s, [Item s]) (Item t, [Item t])
forall (p :: * -> * -> *) a b c d.
Monoidal p =>
p a b -> p c d -> p (a, c) (b, d)
>*< p (Item s) (Item t) -> p [Item s] [Item t]
forall a b. p a b -> p [a] [b]
forall (p :: * -> * -> *) a b. Distributor p => p a b -> p [a] [b]
manyP (p () ()
sep p () () -> p (Item s) (Item t) -> p (Item s) (Item t)
forall (p :: * -> * -> *) c a b.
Monoidal p =>
p () c -> p a b -> p a b
>* p (Item s) (Item t)
p)) p (Item s, [Item s]) (Item t, [Item t])
-> p () () -> p (Item s, [Item s]) (Item t, [Item t])
forall (p :: * -> * -> *) a b c.
Monoidal p =>
p a b -> p () c -> p a b
*< p () ()
end

{- | Use a nilary constructor pattern to sequence zero times, or
associate a binary constructor pattern to sequence one or more times. -}
chain
  :: Alternator p
  => (forall x. x -> Either x x) -- ^ `Left` or `Right` associate
  -> APartialIso a b (a,a) (b,b) -- ^ binary constructor pattern
  -> APrism a b () () -- ^ nilary constructor pattern
  -> SepBy (p () ()) -> p a b -> p a b
chain :: forall (p :: * -> * -> *) a b.
Alternator p =>
(forall x. x -> Either x x)
-> APartialIso a b (a, a) (b, b)
-> APrism a b () ()
-> SepBy (p () ())
-> p a b
-> p a b
chain forall x. x -> Either x x
association APartialIso a b (a, a) (b, b)
pat2 APrism a b () ()
pat0 (SepBy p () ()
beg p () ()
end p () ()
sep) p a b
p =
  p () ()
beg p () () -> p a b -> p a b
forall (p :: * -> * -> *) c a b.
Monoidal p =>
p () c -> p a b -> p a b
>* APrism a b () () -> p a b -> p a b
forall a b. APrism a b () () -> p a b -> p a b
forall (p :: * -> * -> *) a b.
Alternator p =>
APrism a b () () -> p a b -> p a b
optionP APrism a b () ()
pat0 ((forall x. x -> Either x x)
-> APartialIso a b (a, a) (b, b)
-> SepBy (p () ())
-> p a b
-> p a b
forall (p :: * -> * -> *) a b.
(Distributor p, Choice p) =>
(forall x. x -> Either x x)
-> APartialIso a b (a, a) (b, b)
-> SepBy (p () ())
-> p a b
-> p a b
chain1 x -> Either x x
forall x. x -> Either x x
association APartialIso a b (a, a) (b, b)
pat2 (p () () -> SepBy (p () ())
forall (p :: * -> *). Applicative p => p () -> SepBy (p ())
sepBy p () ()
sep) p a b
p) p a b -> p () () -> p a b
forall (p :: * -> * -> *) a b c.
Monoidal p =>
p a b -> p () c -> p a b
*< p () ()
end

{- | Associate a binary constructor pattern to sequence one or more times. -}
chain1
  :: (Distributor p, Choice p)
  => (forall x. x -> Either x x) -- ^ `Left` or `Right` associate
  -> APartialIso a b (a,a) (b,b) -- ^ binary constructor pattern
  -> SepBy (p () ()) -> p a b -> p a b
chain1 :: forall (p :: * -> * -> *) a b.
(Distributor p, Choice p) =>
(forall x. x -> Either x x)
-> APartialIso a b (a, a) (b, b)
-> SepBy (p () ())
-> p a b
-> p a b
chain1 forall x. x -> Either x x
association APartialIso a b (a, a) (b, b)
pat (SepBy p () ()
beg p () ()
end p () ()
sep) = (p a b -> p a b) -> (p a b -> p a b) -> p a b -> p a b
leftOrRight p a b -> p a b
chainl1 p a b -> p a b
chainr1
  where
    leftOrRight :: (p a b -> p a b) -> (p a b -> p a b) -> p a b -> p a b
leftOrRight p a b -> p a b
a p a b -> p a b
b = case () -> Either () ()
forall x. x -> Either x x
association () of Left ()
_ -> p a b -> p a b
a; Right ()
_ -> p a b -> p a b
b
    chainl1 :: p a b -> p a b
chainl1 p a b
p = APartialIso a b (a, a) (b, b) -> Prism a b (a, [a]) (b, [b])
forall t s a b d c.
(AsEmpty t, Cons s t a b) =>
APartialIso d c (d, b) (c, a) -> Prism d c (d, t) (c, s)
difoldl APartialIso a b (a, a) (b, b)
pat (Market (a, [a]) (b, [b]) (a, [a]) (Identity (b, [b]))
 -> Market (a, [a]) (b, [b]) a (Identity b))
-> p (a, [a]) (b, [b]) -> p a b
forall (p :: * -> * -> *) s t a b.
Choice p =>
APrism s t a b -> p a b -> p s t
>? p () ()
beg p () () -> p a b -> p a b
forall (p :: * -> * -> *) c a b.
Monoidal p =>
p () c -> p a b -> p a b
>* p a b
p p a b -> p [a] [b] -> p (a, [a]) (b, [b])
forall (p :: * -> * -> *) a b c d.
Monoidal p =>
p a b -> p c d -> p (a, c) (b, d)
>*< p a b -> p [a] [b]
forall a b. p a b -> p [a] [b]
forall (p :: * -> * -> *) a b. Distributor p => p a b -> p [a] [b]
manyP (p () ()
sep p () () -> p a b -> p a b
forall (p :: * -> * -> *) c a b.
Monoidal p =>
p () c -> p a b -> p a b
>* p a b
p) p [a] [b] -> p () () -> p [a] [b]
forall (p :: * -> * -> *) a b c.
Monoidal p =>
p a b -> p () c -> p a b
*< p () ()
end
    chainr1 :: p a b -> p a b
chainr1 p a b
p = APartialIso a b (a, a) (b, b) -> Prism a b ([a], a) ([b], b)
forall t s a b d c.
(AsEmpty t, Cons s t a b) =>
APartialIso d c (b, d) (a, c) -> Prism d c (t, d) (s, c)
difoldr APartialIso a b (a, a) (b, b)
pat (Market ([a], a) ([b], b) ([a], a) (Identity ([b], b))
 -> Market ([a], a) ([b], b) a (Identity b))
-> p ([a], a) ([b], b) -> p a b
forall (p :: * -> * -> *) s t a b.
Choice p =>
APrism s t a b -> p a b -> p s t
>? p () ()
beg p () () -> p [a] [b] -> p [a] [b]
forall (p :: * -> * -> *) c a b.
Monoidal p =>
p () c -> p a b -> p a b
>* p a b -> p [a] [b]
forall a b. p a b -> p [a] [b]
forall (p :: * -> * -> *) a b. Distributor p => p a b -> p [a] [b]
manyP (p a b
p p a b -> p () () -> p a b
forall (p :: * -> * -> *) a b c.
Monoidal p =>
p a b -> p () c -> p a b
*< p () ()
sep) p [a] [b] -> p a b -> p ([a], a) ([b], b)
forall (p :: * -> * -> *) a b c d.
Monoidal p =>
p a b -> p c d -> p (a, c) (b, d)
>*< p a b
p p a b -> p () () -> p a b
forall (p :: * -> * -> *) a b c.
Monoidal p =>
p a b -> p () c -> p a b
*< p () ()
end

{- | Add a `SepBy` to `replicateP` using `intercalateP`. -}
intercalateP
  :: (Monoidal p, Choice p, AsEmpty s, Cons s s a a)
  => Int {- ^ number of repetitions -}
  -> SepBy (p () ()) -> p a a -> p s s
intercalateP :: forall (p :: * -> * -> *) s a.
(Monoidal p, Choice p, AsEmpty s, Cons s s a a) =>
Int -> SepBy (p () ()) -> p a a -> p s s
intercalateP Int
n (SepBy p () ()
beg p () ()
end p () ()
_) p a a
_ | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 =
  p () ()
beg p () () -> p s s -> p s s
forall (p :: * -> * -> *) c a b.
Monoidal p =>
p () c -> p a b -> p a b
>* p s s
forall s (p :: * -> * -> *).
(AsEmpty s, Monoidal p, Choice p) =>
p s s
asEmpty p s s -> p () () -> p s s
forall (p :: * -> * -> *) a b c.
Monoidal p =>
p a b -> p () c -> p a b
*< p () ()
end
intercalateP Int
n (SepBy p () ()
beg p () ()
end p () ()
comma) p a a
p =
  p () ()
beg p () () -> p a a -> p a a
forall (p :: * -> * -> *) c a b.
Monoidal p =>
p () c -> p a b -> p a b
>* p a a
p p a a -> p s s -> p s s
forall s t a b (p :: * -> * -> *).
(Cons s t a b, Monoidal p, Choice p) =>
p a b -> p s t -> p s t
>:< Int -> p a a -> p s s
forall (p :: * -> * -> *) s a.
(Monoidal p, Choice p, AsEmpty s, Cons s s a a) =>
Int -> p a a -> p s s
replicateP (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) (p () ()
comma p () () -> p a a -> p a a
forall (p :: * -> * -> *) c a b.
Monoidal p =>
p () c -> p a b -> p a b
>* p a a
p) p s s -> p () () -> p s s
forall (p :: * -> * -> *) a b c.
Monoidal p =>
p a b -> p () c -> p a b
*< p () ()
end