-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Isos & Lens for Data.Diverse.Many and Prisms for Data.Diverse.Which
--   
--   Isos &amp; Lens for Data.Diverse.Many and Prisms for
--   Data.Diverse.Which Refer to <a>ManySpec.hs</a> and <a>WhichSpec.hs</a>
--   for example usages.
@package data-diverse-lens
@version 2.1.0.0

module Data.Diverse.Lens.Many

-- | <pre>
--   _Many = iso fromMany toMany
--   </pre>
_Many :: IsMany t xs a => Iso' (Many xs) (t xs a)

-- | <pre>
--   _Many' = iso fromMany' toMany'
--   </pre>
_Many' :: IsMany Tagged xs a => Iso' (Many xs) a

-- | Polymorphic version of <a>item'</a>
class HasItem a b s t | s a b -> t, t a b -> s
item :: HasItem a b s t => Lens s t a b

-- | <a>fetch</a> (<a>view</a> <a>item</a>) and <a>replace'</a> (<a>set</a>
--   <a>item'</a>) in <a>Lens'</a> form.
--   
--   <pre>
--   let x = (5 :: Int) <a>./</a> False <a>./</a> 'X' <a>./</a> Just 'O' <a>./</a> <a>nil</a>
--   x <a>^.</a> <a>item'</a> @Int `shouldBe` 5
--   (x <a>&amp;</a> <a>item'</a> @Int .~ 6) `shouldBe` (6 :: Int) <a>./</a> False <a>./</a> 'X' <a>./</a> Just 'O' <a>./</a> <a>nil</a>
--   </pre>
class HasItem' a s

-- | Make it easy to create an instance of <a>item</a> using <a>Typed</a>
item' :: HasItem' a s => Lens' s a

-- | Make it easy to create an instance of <a>item</a> using <a>Typed</a>
item' :: (HasItem' a s, (HasType a s)) => Lens' s a

-- | Polymorphic version of <a>itemL'</a>
--   
--   <pre>
--   let x = (5 :: Int) <a>./</a> Tagged @Foo False <a>./</a> Tagged @Bar 'X' <a>./</a> <a>nil</a>
--   (x <a>&amp;</a> <a>itemL</a> @Foo <a>.~</a> "foo") `shouldBe` (5 :: Int) <a>./</a> "foo" <a>./</a> Tagged @Bar 'X' <a>./</a> <a>nil</a>
--   </pre>
class HasItemL (l :: k) a b s t | s l -> a, t l -> b, s l b -> t, t l a -> s
itemL :: HasItemL l a b s t => Lens s t a b

-- | <a>fetchL</a> (<a>view</a> <a>itemL</a>) and <a>replaceL</a>
--   (<a>set</a> <a>itemL</a>) in <a>Lens'</a> form.
--   
--   <pre>
--   let x = (5 :: Int) <a>./</a> Tagged @Foo False <a>./</a> Tagged @Bar 'X' <a>./</a> <a>nil</a>
--   x <a>^.</a> <a>itemL'</a> @Foo `shouldBe` Tagged @Foo False
--   (x <a>&amp;</a> <a>itemL'</a> @Foo <a>.~</a> Tagged @Foo True) `shouldBe` (5 :: Int) <a>./</a> Tagged @Foo True <a>./</a> Tagged @Bar 'X' <a>./</a> <a>nil</a>
--   </pre>
class HasItemL' (l :: k) a s | s l -> a
itemL' :: HasItemL' l a s => Lens' s a

-- | Variation of <a>itemL</a> that automatically tags and untags the
--   field.
class HasItemTag (l :: k) a b s t | s l -> a, t l -> b, s l b -> t, t l a -> s
itemTag :: HasItemTag l a b s t => Lens s t a b

-- | Variation of <a>itemL'</a> that automatically tags and untags the
--   field. A default implementation using generics is not provided as it
--   make GHC think that <tt>l</tt> must be type <tt>Symbol</tt> when
--   <tt>l</tt> can actually be any kind. Create instances of
--   <a>HasItemTag'</a> using <a>Data.Generics.Product.Fields</a> as
--   follows: <tt> instance HasField' l Foo a =&gt; HasItemTag' l a Foo
--   where itemTag' = field </tt>l @
class HasItemTag' (l :: k) a s
itemTag' :: HasItemTag' l a s => Lens' s a

-- | Polymorphic version of <a>itemN'</a>
class HasItemN (n :: Nat) a b s t | s n -> a, t n -> b, s n b -> t, t n a -> s

-- | Make it easy to create an instance of <a>itemN</a> using
--   <a>Positions</a>
itemN :: HasItemN n a b s t => Lens s t a b

-- | Make it easy to create an instance of <a>itemN</a> using
--   <a>Positions</a>
itemN :: (HasItemN n a b s t, (HasPosition n s t a b)) => Lens s t a b

-- | <a>fetchN</a> (<a>view</a> <a>item</a>) and <a>replaceN'</a>
--   (<a>set</a> <a>item'</a>) in <a>Lens'</a> form.
--   
--   <pre>
--   let x = (5 :: Int) <a>./</a> False <a>./</a> 'X' <a>./</a> Just 'O' <a>./</a> (6 :: Int) <a>./</a> Just 'A' ./ nil
--   x <a>^.</a> <a>itemN'</a> @0 `shouldBe` 5
--   (x <a>&amp;</a> <a>itemN'</a> @0 <a>.~</a> 6) `shouldBe` (6 :: Int) <a>./</a> False <a>./</a> 'X' <a>./</a> Just 'O' <a>./</a> (6 :: Int) <a>./</a> Just 'A' <a>./</a> <a>nil</a>
--   </pre>
class HasItemN' (n :: Nat) a s | s n -> a
itemN' :: HasItemN' n a s => Lens' s a

-- | A friendlier constraint synonym for <a>project</a>.
type Project (smaller :: [Type]) (smaller' :: [Type]) (larger :: [Type]) (larger' :: [Type]) = (Select smaller larger, Amend smaller smaller' larger, larger' ~ Replaces smaller smaller' larger)

-- | Polymorphic version of project'
project :: forall smaller smaller' larger larger'. Project smaller smaller' larger larger' => Lens (Many larger) (Many larger') (Many smaller) (Many smaller')

-- | A friendlier constraint synonym for <a>project'</a>.
type Project' (smaller :: [Type]) (larger :: [Type]) = (Select smaller larger, Amend' smaller larger)

-- | <a>select</a> (<a>view</a> <a>project</a>) and <a>amend</a>
--   (<a>set</a> <a>project</a>) in <a>Lens'</a> form.
--   
--   <pre>
--   <a>project</a> = <a>lens</a> <a>select</a> <a>amend</a>
--   </pre>
--   
--   <pre>
--   let x = (5 :: Int) <a>./</a> False <a>./</a> 'X' <a>./</a> Just 'O' <a>./</a> <a>nil</a>
--   x <a>^.</a> (<a>project'</a> @_ @'[Int, Maybe Char]) `shouldBe` (5 :: Int) <a>./</a> Just 'O' <a>./</a> <a>nil</a>
--   (x <a>&amp;</a> (<a>project'</a> @_ @'[Int, Maybe Char]) <a>.~</a> ((6 :: Int) <a>./</a> Just <tt>P</tt> <a>./</a> <a>nil</a>)) `shouldBe`
--       (6 :: Int) <a>./</a> False <a>./</a> 'X' <a>./</a> Just 'P' <a>./</a> <a>nil</a>
--   </pre>
project' :: forall smaller larger. Project' smaller larger => Lens' (Many larger) (Many smaller)

-- | A friendlier constraint synonym for <a>projectL</a>.
type ProjectL (ls :: [k]) (smaller :: [Type]) (smaller' :: [Type]) (larger :: [Type]) (larger' :: [Type]) = (Select smaller larger, Amend smaller smaller' larger, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger, larger' ~ Replaces smaller smaller' larger)

-- | Polymorphic version of <a>projectL'</a>
--   
--   <pre>
--   let x = False <a>./</a> Tagged @"Hi" (5 :: Int) <a>./</a> Tagged @Foo False <a>./</a> Tagged @Bar 'X' <a>./</a> Tagged @"Bye" 'O' <a>./</a> <a>nil</a>
--   (x <a>&amp;</a> (<a>projectL</a> @'["Hi", "Bye"] <a>.~</a> (True <a>./</a> Tagged @"Changed" False <a>./</a> <a>nil</a>)) `shouldBe`
--       False <a>./</a> True <a>./</a> Tagged @Foo False <a>./</a> Tagged @Bar 'X' <a>./</a> Tagged @"Changed" False <a>./</a> <a>nil</a>
--   </pre>
projectL :: forall ls smaller smaller' larger larger'. ProjectL ls smaller smaller' larger larger' => Lens (Many larger) (Many larger') (Many smaller) (Many smaller')

-- | A friendlier constraint synonym for <a>projectL'</a>.
type ProjectL' (ls :: [k]) (smaller :: [Type]) (larger :: [Type]) = (Select smaller larger, Amend' smaller larger, smaller ~ KindsAtLabels ls larger, IsDistinct ls, UniqueLabels ls larger)

-- | <a>selectL</a> (<a>view</a> <a>projectL</a>) and <a>amendL</a>
--   (<a>set</a> <a>projectL</a>) in <a>Lens'</a> form.
--   
--   <pre>
--   let x = False <a>./</a> Tagged @"Hi" (5 :: Int) <a>./</a> Tagged @Foo False <a>./</a> Tagged @Bar 'X' <a>./</a> Tagged @"Bye" 'O' <a>./</a> <a>nil</a>
--   x <a>^.</a> (<a>projectL'</a> @'[Foo, Bar] `shouldBe` Tagged @Foo False <a>./</a> Tagged @Bar 'X' <a>./</a> nil
--   (x <a>&amp;</a> (<a>projectL'</a> @'["Hi", "Bye"] <a>.~</a> (Tagged @"Hi" (6 :: Int) <a>./</a> Tagged @"Bye" 'P' <a>./</a> nil)) '<tt>shouldBe</tt>
--       False <a>./</a> Tagged @"Hi" (6 :: Int) <a>./</a> Tagged @Foo False <a>./</a> Tagged @Bar 'X' <a>./</a> Tagged @"Bye" 'P' <a>./</a> <a>nil</a>
--   </pre>
projectL' :: forall ls smaller larger. ProjectL' ls smaller larger => Lens' (Many larger) (Many smaller)

-- | A friendlier constraint synonym for <a>projectN</a>.
type ProjectN (ns :: [Nat]) (smaller :: [Type]) (smaller' :: [Type]) (larger :: [Type]) (larger' :: [Type]) = (SelectN ns smaller larger, AmendN ns smaller smaller' larger, larger' ~ ReplacesIndex ns smaller' larger)

-- | Polymorphic version of <a>projectN'</a>
projectN :: forall ns smaller smaller' larger larger'. ProjectN ns smaller smaller' larger larger' => Lens (Many larger) (Many larger') (Many smaller) (Many smaller')

-- | A friendlier constraint synonym for <a>projectN'</a>.
type ProjectN' (ns :: [Nat]) (smaller :: [Type]) (larger :: [Type]) = (SelectN ns smaller larger, AmendN' ns smaller larger)

-- | <a>selectN</a> (<a>view</a> <a>projectN</a>) and <a>amendN</a>
--   (<a>set</a> <a>projectN</a>) in <a>Lens'</a> form.
--   
--   <pre>
--   <a>projectN</a> = <a>lens</a> <a>selectN</a> <a>amendN</a>
--   </pre>
--   
--   <pre>
--   let x = (5 :: Int) <a>./</a> False <a>./</a> 'X' <a>./</a> Just 'O' <a>./</a> (6 :: Int) <a>./</a> Just 'A' <a>./</a> <a>nil</a>
--   x <a>^.</a> <a>projectN</a> @_ @'[5, 4, 0] `shouldBe` Just 'A' <a>./</a> (6 :: Int) <a>./</a> (5 ::Int) <a>./</a> <a>nil</a>
--   (x <a>&amp;</a> <a>projectN</a> @_ @'[5, 4, 0] <a>.~</a> (Just 'B' <a>./</a> (8 :: Int) <a>./</a> (4 ::Int) <a>./</a> nil)) `shouldBe`
--       (4 :: Int) <a>./</a> False <a>./</a> 'X' <a>./</a> Just 'O' <a>./</a> (8 :: Int) <a>./</a> Just 'B' <a>./</a> <a>nil</a>
--   </pre>
projectN' :: forall ns smaller larger. ProjectN' ns smaller larger => Lens' (Many larger) (Many smaller)
instance (Data.Diverse.TypeLevel.MemberAt n x xs, ys ~ Data.Diverse.TypeLevel.ReplaceIndex n y xs) => Data.Diverse.Lens.Many.HasItemN n x y (Data.Diverse.Many.Internal.Many xs) (Data.Diverse.Many.Internal.Many ys)
instance Data.Diverse.TypeLevel.MemberAt n x xs => Data.Diverse.Lens.Many.HasItemN' n x (Data.Diverse.Many.Internal.Many xs)
instance forall k (l :: k) (xs :: [*]) x (ys :: [*]) y. (Data.Diverse.TypeLevel.UniqueLabelMember l xs, Data.Tagged.Tagged l x ~ Data.Diverse.TypeLevel.KindAtLabel l xs, ys ~ Data.Diverse.TypeLevel.Replace (Data.Tagged.Tagged l x) (Data.Tagged.Tagged l y) xs) => Data.Diverse.Lens.Many.HasItemTag l x y (Data.Diverse.Many.Internal.Many xs) (Data.Diverse.Many.Internal.Many ys)
instance forall k (l :: k) (xs :: [*]) x. (Data.Diverse.TypeLevel.UniqueLabelMember l xs, Data.Tagged.Tagged l x ~ Data.Diverse.TypeLevel.KindAtLabel l xs) => Data.Diverse.Lens.Many.HasItemTag' l x (Data.Diverse.Many.Internal.Many xs)
instance forall k (l :: k) (xs :: [*]) x (ys :: [*]) y. (Data.Diverse.TypeLevel.UniqueLabelMember l xs, x ~ Data.Diverse.TypeLevel.KindAtLabel l xs, ys ~ Data.Diverse.TypeLevel.Replace x y xs) => Data.Diverse.Lens.Many.HasItemL l x y (Data.Diverse.Many.Internal.Many xs) (Data.Diverse.Many.Internal.Many ys)
instance forall k (l :: k) (xs :: [*]) x. (Data.Diverse.TypeLevel.UniqueLabelMember l xs, x ~ Data.Diverse.TypeLevel.KindAtLabel l xs) => Data.Diverse.Lens.Many.HasItemL' l x (Data.Diverse.Many.Internal.Many xs)
instance (Data.Diverse.TypeLevel.UniqueMember x xs, ys ~ Data.Diverse.TypeLevel.Replace x y xs) => Data.Diverse.Lens.Many.HasItem x y (Data.Diverse.Many.Internal.Many xs) (Data.Diverse.Many.Internal.Many ys)
instance Data.Diverse.TypeLevel.UniqueMember x xs => Data.Diverse.Lens.Many.HasItem' x (Data.Diverse.Many.Internal.Many xs)

module Data.Diverse.Lens.Which

-- | <a>pick</a> (<a>review</a> <a>facet</a>) and <a>trial</a>
--   (<a>preview</a> <a>facet</a>) in <a>Prism'</a> form.
--   
--   <pre>
--   <a>facet</a> = <a>prism'</a> <a>pick</a> (<a>trial'</a>)
--   </pre>
--   
--   <pre>
--   let y = <a>review</a> (<a>facet</a> @Int) (5 :: Int) :: <a>Which</a> '[Bool, Int, Char, Bool, Char] -- <a>pick</a>
--       x = <a>preview</a> (<a>facet</a> @Int) y -- <a>trial</a>
--   x `shouldBe` (Just 5)
--   </pre>
class AsFacet a s

-- | Make it easy to create an instance of <a>AsFacet</a> using
--   <a>Typed</a>
facet :: AsFacet a s => Prism' s a

-- | Make it easy to create an instance of <a>AsFacet</a> using
--   <a>Typed</a>
facet :: (AsFacet a s, (AsType a s)) => Prism' s a
class AsFacet a s => MatchingFacet a s t | s a -> t

-- | Unfortunately, polymorphic <tt>Prism s t a b</tt> cannot be used as it
--   can only be created with: <tt> (UniqueMember x xs, UniqueMember y ys,
--   ys ~ Remove x xs) =&gt; prism (pick :: y -&gt; Which ys) (trial ::
--   Which xs -&gt; Either (Which ys) x) </tt> This above causes problems
--   when used monomorphically with <tt>s ~ t</tt> and <tt>x ~ y</tt> since
--   <tt>xs</tt> cannot equal <tt>ys ~ Remove x x</tt>.
--   
--   What is desirec is: (UniqueMember x xs, ys ~ Remove x xs) =&gt; prism_
--   (pick :: x -&gt; Which xs) (trial :: Which xs -&gt; Either (Which ys)
--   x)
--   
--   So we expose the polymorhpic <a>matching</a> explicitly.
matchingFacet :: MatchingFacet a s t => s -> Either t a

-- | <a>pickL</a> (<a>review</a> <a>facetL</a>) and <a>trialL'</a>
--   (<a>preview</a> <tt>facetL'</tt>) in <a>Prism'</a> form.
--   
--   <pre>
--   let y = <a>review</a> <a>facetL</a> @Bar (Tagged (5 :: Int)) :: Which '[Tagged Foo Bool, Tagged Bar Int, Char, Bool, Char]
--       x = <a>preview</a> <a>facetL</a> @Bar y
--   x `shouldBe` (Just (Tagged 5))
--   </pre>
class AsFacetL (l :: k) a s | s l -> a
facetL :: AsFacetL l a s => Prism' s a

-- | Labelled version of <a>MatchingFacet</a>
class AsFacetL l a s => MatchingFacetL l a s t | s a -> t
matchingFacetL :: MatchingFacetL l a s t => s -> Either t a

-- | Variation of <tt>fetchL</tt> specialized to <a>Tagged</a> which
--   automatically tags and untags the field. A default implementation
--   using generics is not provided as it make GHC think that <tt>l</tt>
--   must be type <tt>Symbol</tt> when <tt>l</tt> can actually be any kind.
--   Create instances of <tt>AsFacetTag'</tt> using
--   <a>Data.Generics.Sum.Constructors</a> as follows: <tt> instance
--   AsConstructor' l Foo Foo a a =&gt; AsFacetTag l a Foo where facetTag =
--   _Ctor </tt>l @
class AsFacetTag (l :: k) a s | s l -> a
facetTag :: AsFacetTag l a s => Prism' s a

-- | Untagged version of <a>MatchingFacet</a>
class AsFacetTag l a s => MatchingFacetTag l a s t | l s a -> t
matchingFacetTag :: MatchingFacetTag l a s t => s -> Either t a

-- | <a>pickN</a> (<a>review</a> <a>facetN</a>) and <a>trialN</a>
--   (<a>preview</a> <a>facetN</a>) in <a>Prism'</a> form.
--   
--   <pre>
--   <a>facetN</a> p = <a>prism'</a> (<a>pickN</a> p) (<a>trialN'</a> p)
--   </pre>
--   
--   <pre>
--   let y = <a>review</a> (<a>facetN</a> @4) (5 :: Int) :: <a>Which</a> '[Bool, Int, Char, Bool, Int, Char] -- <a>pickN</a>
--       x = <a>preview</a> (<a>facetN</a> @4) y -- <a>trialN</a>
--   x `shouldBe` (Just 5)
--   </pre>
class AsFacetN (n :: Nat) a s | s n -> a
facetN :: AsFacetN n a s => Prism' s a

-- | Nat indexed version of <a>MatchingFacet</a>
class AsFacetN n a s => MatchingFacetN n a s t | s a -> t
matchingFacetN :: MatchingFacetN n a s t => s -> Either t a

-- | A friendlier constraint synonym for <a>inject</a>
type Inject (branch :: [Type]) (tree :: [Type]) = (Diversify branch tree, Reinterpret' branch tree)

-- | <a>diversify</a> (<a>review</a> <a>inject</a>) and <a>reinterpret'</a>
--   (<a>preview</a> <a>inject</a>) in <a>Prism'</a> form.
--   
--   <pre>
--   let x = <a>pick</a> (5 :: Int) :: <a>Which</a> '[String, Int]
--       y = <a>review</a> (<a>inject</a> @_  @_ @[Bool, Int, Char, String]) x -- <a>diversify</a>
--   y `shouldBe` pick (5 :: Int) :: <a>Which</a> '[Bool, Int, Char, String]
--   let y' = <a>preview</a> (<a>inject</a> @_ @[String, Int]) y -- <a>reinterpret</a>
--   y' `shouldBe` Just (pick (5 :: Int)) :: Maybe (<a>Which</a> '[String, Int])
--   </pre>
inject :: forall branch tree. (Inject branch tree) => Prism' (Which tree) (Which branch)

-- | A friendlier constraint synonym for <a>injectL</a>
type InjectL (ls :: [k]) (branch :: [Type]) (tree :: [Type]) = (Diversify branch tree, Reinterpret' branch tree, branch ~ KindsAtLabels ls tree, UniqueLabels ls tree, IsDistinct ls)

-- | <a>diversifyL</a> (<a>review</a> <a>injectL</a>) and
--   <a>reinterpretL'</a> (<a>preview</a> <a>injectL</a>) in <a>Prism'</a>
--   form.
--   
--   <pre>
--   let t = <a>pick</a> @[Tagged Bar Int, Tagged Foo Bool, Tagged Hi Char, Tagged Bye Bool] (5 :: Tagged Bar Int)
--       b = <a>pick</a> @'[Tagged Foo Bool, Tagged Bar Int] (5 :: Tagged Bar Int)
--       t' = <a>review</a> (<a>injectL</a> @_ @[Foo, Bar] @_ @[Tagged Bar Int, Tagged Foo Bool, Tagged Hi Char, Tagged Bye Bool]) b
--       b' = <a>preview</a> (<a>injectL</a> @_ @[Foo, Bar]) t'
--   t `shouldBe` t'
--   b' `shouldBe` Just b
--   </pre>
injectL :: forall ls branch tree. InjectL ls branch tree => Prism' (Which tree) (Which branch)

-- | A friendlier constraint synonym for <a>injectN</a>
type InjectN (ns :: [Nat]) (branch :: [Type]) (tree :: [Type]) = (DiversifyN ns branch tree, ReinterpretN' ns branch tree)

-- | <a>diversifyN</a> (<a>review</a> <a>injectN</a>) and
--   <a>reinterpretN'</a> (<a>preview</a> <a>injectN</a>) in <a>Prism'</a>
--   form.
--   
--   <pre>
--   let x = <a>pick</a> (5 :: Int) :: <a>Which</a> '[String, Int]
--       y = <a>review</a> (injectN @_ @[3, 1] @_ @[Bool, Int, Char, String]) x -- <a>diversifyN</a>
--   y `shouldBe` pick (5 :: Int) :: <a>Which</a> '[Bool, Int, Char, String]
--   let y' = <a>preview</a> (<a>injectN</a> @_ @[3, 1] @[String, Int]) y -- <tt>reinterpertN'</tt>
--   y' `shouldBe` Just (<a>pick</a> (5 :: Int)) :: Maybe (<a>Which</a> '[String, Int])
--   </pre>
injectN :: forall ns branch tree. InjectN ns branch tree => Prism' (Which tree) (Which branch)
instance (Data.Diverse.TypeLevel.MemberAt n x xs, ys ~ Data.Diverse.TypeLevel.RemoveIndex n xs) => Data.Diverse.Lens.Which.MatchingFacetN n x (Data.Diverse.Which.Internal.Which xs) (Data.Diverse.Which.Internal.Which ys)
instance Data.Diverse.TypeLevel.MemberAt n x xs => Data.Diverse.Lens.Which.AsFacetN n x (Data.Diverse.Which.Internal.Which xs)
instance forall k (l :: k) (xs :: [*]) x (ys :: [*]). (Data.Diverse.TypeLevel.UniqueLabelMember l xs, Data.Tagged.Tagged l x ~ Data.Diverse.TypeLevel.KindAtLabel l xs, ys ~ Data.Diverse.TypeLevel.Remove (Data.Tagged.Tagged l x) xs) => Data.Diverse.Lens.Which.MatchingFacetTag l x (Data.Diverse.Which.Internal.Which xs) (Data.Diverse.Which.Internal.Which ys)
instance forall k (l :: k) (xs :: [*]) x. (Data.Diverse.TypeLevel.UniqueLabelMember l xs, Data.Tagged.Tagged l x ~ Data.Diverse.TypeLevel.KindAtLabel l xs) => Data.Diverse.Lens.Which.AsFacetTag l x (Data.Diverse.Which.Internal.Which xs)
instance forall k (l :: k) (xs :: [*]) x (ys :: [*]). (Data.Diverse.TypeLevel.UniqueLabelMember l xs, x ~ Data.Diverse.TypeLevel.KindAtLabel l xs, ys ~ Data.Diverse.TypeLevel.Remove x xs) => Data.Diverse.Lens.Which.MatchingFacetL l x (Data.Diverse.Which.Internal.Which xs) (Data.Diverse.Which.Internal.Which ys)
instance forall k (l :: k) (xs :: [*]) x. (Data.Diverse.TypeLevel.UniqueLabelMember l xs, x ~ Data.Diverse.TypeLevel.KindAtLabel l xs) => Data.Diverse.Lens.Which.AsFacetL l x (Data.Diverse.Which.Internal.Which xs)
instance (Data.Diverse.TypeLevel.UniqueMember x xs, ys ~ Data.Diverse.TypeLevel.Remove x xs) => Data.Diverse.Lens.Which.MatchingFacet x (Data.Diverse.Which.Internal.Which xs) (Data.Diverse.Which.Internal.Which ys)
instance Data.Diverse.TypeLevel.UniqueMember x xs => Data.Diverse.Lens.Which.AsFacet x (Data.Diverse.Which.Internal.Which xs)

module Data.Diverse.Lens

module Data.Diverse.Profunctor.Many

-- | A friendlier constraint synonym for <a>itemized</a>.
type Itemized a b s t = (HasItem a b s t, HasItem' a s)

-- | Like <a>Strong</a> or <a>Arrow</a> but lifting into <a>Many</a>
itemized :: forall w a b s t. (Profunctor w, Strong w, Itemized a b s t) => w a b -> w s t

-- | Like <a>Strong</a> or <a>Arrow</a> but lifting into <a>Many</a> of one
--   type
itemized' :: Profunctor w => w a b -> w (Many '[a]) (Many '[b])

-- | A friendlier constraint synonym for <a>projected</a>.
type Projected a1 a2 b1 b2 = (Select a1 a2, Amend a1 b1 a2, b2 ~ Replaces a1 b1 a2)

-- | Like <a>Strong</a> or <a>Arrow</a> but lifting from a <a>Many</a> to a
--   <a>Many</a> of another type
projected :: forall proxy w a1 a2 b1 b2. (Profunctor w, Strong w, Projected a1 a2 b1 b2) => proxy a2 -> w (Many a1) (Many b1) -> w (Many a2) (Many b2)

-- | A friendlier constraint synonym for <a>*&amp;&amp;*</a>.
type SelectWith a1 a2 a3 b1 b2 b3 = (Select a1 (AppendUnique a1 a2), Select a2 (AppendUnique a1 a2), a3 ~ AppendUnique a1 a2, b3 ~ Append b1 b2)

-- | Split the input between the two argument arrows and combine their
--   output. The type of the resultant input is a <a>Many</a> of all the
--   unique types in the argument arrows' inputs, The type of the resultant
--   output is a concatenated <a>Many</a> of the arguments arrows' outputs.
--   Analogous to a <a>Many</a> combination of both of <a>***</a> and
--   <a>&amp;&amp;&amp;</a>. It is a compile error if the types are not
--   distinct in each of the argument arrow inputs.
(*&&*) :: forall w a1 a2 a3 b1 b2 b3. (Category w, Profunctor w, Strong w, SelectWith a1 a2 a3 b1 b2 b3) => w (Many a1) (Many b1) -> w (Many a2) (Many b2) -> w (Many a3) (Many b3)
infixr 3 *&&*

-- | A friendlier constraint synonym for <a>&gt;&amp;&amp;&gt;</a>.
type ThenSelect a2 b1 b2 b3 = (Select (Complement b1 a2) b1, Select a2 b1, b3 ~ Append (Complement b1 a2) b2)

-- | Left-to-right chaining of arrows one after another, where left over
--   input not consumed by the right arrow is forwarded to the output. It
--   is a compile error if the types are not distinct in each of the
--   argument arrow inputs, or if the input of the second arrow is not a
--   subset of the output of the first arrow.
(>&&>) :: forall w a a2 b1 b2 b3. (Category w, Profunctor w, Strong w, ThenSelect a2 b1 b2 b3) => w a (Many b1) -> w (Many a2) (Many b2) -> w a (Many b3)
infixr 3 >&&>

-- | right-to-left version of '(&gt;&amp;&amp;&gt;)'
(<&&<) :: (Category w, Profunctor w, Strong w, ThenSelect a2 b1 b2 b3) => w (Many a2) (Many b2) -> w a (Many b1) -> w a (Many b3)
infixl 2 <&&<

module Data.Diverse.Profunctor.Which

-- | A friendlier constraint synonym for <a>faceted</a>.
type Faceted a as x b bs y = (MatchingFacet a x y, AsFacet b y)

-- | Like <a>Choice</a> or <tt>ArrowChoice</tt> but lifting into a
--   polymorphic variant.
faceted :: forall w a as x b bs y. (Profunctor w, Choice w, Faceted a as x b bs y) => w a b -> w x y

-- | Like <a>Choice</a> or <tt>ArrowChoice</tt> but lifting into
--   <a>Which</a> of one type
faceted' :: (Profunctor w, Choice w) => w a b -> w (Which '[a]) (Which '[b])

-- | A friendlier constraint synonym for <a>injected</a>.
type Injected a a' b b' = (Reinterpret a a', Diversify b (AppendUnique (Complement a' a) b), Diversify (Complement a' a) (AppendUnique (Complement a' a) b), b' ~ AppendUnique (Complement a' a) b, Complement a a' ~ '[])

-- | Like <a>Choice</a> or <tt>ArrowChoice</tt> but lifting from
--   <a>Which</a> into another type of <a>Which</a> NB. It is a compile
--   error if all of the input types in the second arrow <tt>a</tt> is not
--   the output types of the first arrow. This prevents surprising
--   behaviour where the second arrow is ignored.
injected :: (Profunctor w, Choice w, Injected a a' b b') => w (Which a) (Which b) -> w (Which a') (Which b')

-- | A friendlier constraint synonym for <a>+||+</a>.
type ChooseBetween a1 a2 a3 b1 b2 b3 = (Reinterpret a2 (Append a1 a2), a1 ~ Complement (Append a1 a2) a2, a3 ~ Append a1 a2, Diversify b1 (AppendUnique b1 b2), Diversify b2 (AppendUnique b1 b2), b3 ~ AppendUnique b1 b2)

-- | Split the input between the two argument arrows, retagging and merging
--   their outputs. The output is merged into a <a>Which</a> of unique
--   types. Analogous to a <a>Which</a> combination of both <a>+++</a> and
--   <a>|||</a>. It is a compile error if the types are not distinct after
--   <a>Append</a>ing both argument arrows inputs. This is to prevent
--   accidently processing an input type twice. The compile error will be
--   due to <tt>(Append a1 a2)</tt> which will not satisfy
--   <tt>UniqueMember</tt> constraints in <a>Reinterpret</a>.
(+||+) :: forall w a1 a2 a3 b1 b2 b3. (Category w, Profunctor w, Choice w, ChooseBetween a1 a2 a3 b1 b2 b3) => w (Which a1) (Which b1) -> w (Which a2) (Which b2) -> w (Which a3) (Which b3)
infixr 2 +||+

-- | Left-to-right chaining of arrows one after another, where left over
--   possibilities not handled by the right arrow is forwarded to the
--   output. It is a compile error if the types are not distinct in each of
--   the argument arrow inputs, or if the types are not distinct of each of
--   the argument arrow output, or if the input of the second arrow is not
--   a subset of the output of the first arrow. This is to prevent
--   surprises behaviour of the second arrow being ignored. The compile
--   error will be due to the <tt>Complement c b ~ '[]</tt> constraint.
(>||>) :: forall w a a2 b1 b2 b3. (Category w, Choice w, Injected a2 b1 b2 b3) => w a (Which b1) -> w (Which a2) (Which b2) -> w a (Which b3)
infixr 2 >||>

-- | right-to-left version of '(&gt;||&gt;)'
(<||<) :: forall w a a2 b1 b2 b3. (Category w, Choice w, Injected a2 b1 b2 b3) => w (Which a2) (Which b2) -> w a (Which b1) -> w a (Which b3)
infixl 2 <||<

module Data.Diverse.Profunctor
