diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -8,6 +8,11 @@
 
 # Changelog
 
+* 0.5.1.0
+  - Added faceted, injected, itemized, projected, which is analogous to Profunctor Choice and Strong
+    but using 'Which' and 'Many'
+  - Added +||+ (analogous to +++ and |||), >||>; and *&&* (analogous to *** and &&&), and >&&>.
+
 * 0.5.0.0
   - min bounds: data-diverse >=1.2.1
   - Rerranged type variable for xxxL and xxxN functions so that the
diff --git a/data-diverse-lens.cabal b/data-diverse-lens.cabal
--- a/data-diverse-lens.cabal
+++ b/data-diverse-lens.cabal
@@ -1,5 +1,5 @@
 name:                data-diverse-lens
-version:             0.5.0.0
+version:             0.5.1.0
 synopsis:            Isos & Lens for Data.Diverse.Many and Prisms for Data.Diverse.Which
 description:         Isos & Lens for Data.Diverse.Many and Prisms for Data.Diverse.Which
                      Refer to [ManySpec.hs](https://github.com/louispan/data-diverse-lens/blob/master/test/Data/Diverse/Lens/ManySpec.hs) and [WhichSpec.hs](https://github.com/louispan/data-diverse-lens/blob/master/test/Data/Diverse/Lens/WhichSpec.hs) for example usages.
@@ -20,13 +20,17 @@
   exposed-modules:     Data.Diverse.Lens
                        Data.Diverse.Lens.Many
                        Data.Diverse.Lens.Which
+                       Data.Diverse.Profunctor
+                       Data.Diverse.Profunctor.Many
+                       Data.Diverse.Profunctor.Which
   build-depends:       base >= 4.7 && < 5
-                     , data-diverse >= 1.2.0.1 && < 2
-                     , tagged >= 0.8.5 && < 1
+                     , data-diverse >= 1.2.0.3
+                     , tagged >= 0.8.5
+                     , profunctors >= 5.2
   if impl(ghc >= 8.2.0)
-    build-depends: lens >= 4.15.2 && < 5
+    build-depends: lens >= 4.15.2
   else
-    build-depends: lens >= 4 && < 5
+    build-depends: lens >= 4
   ghc-options:         -Wall
   default-language:    Haskell2010
 
@@ -37,14 +41,14 @@
   other-modules:       Data.Diverse.Lens.ManySpec
                        Data.Diverse.Lens.WhichSpec
   build-depends:       base
-                     , data-diverse >= 1.2.0.1 && < 2
+                     , data-diverse >= 1.2.0.1
                      , data-diverse-lens
-                     , hspec >= 2 && < 3
-                     , tagged >= 0.8.5 && < 1
+                     , hspec >= 2
+                     , tagged >= 0.8.5
   if impl(ghc >= 8.2.0)
-    build-depends: lens >= 4.15.2 && < 5
+    build-depends: lens >= 4.15.2
   else
-    build-depends: lens >= 4 && < 5
+    build-depends: lens >= 4
   ghc-options:         -threaded -rtsopts -with-rtsopts=-N -Wall
   default-language:    Haskell2010
 
diff --git a/src/Data/Diverse/Lens/Many.hs b/src/Data/Diverse/Lens/Many.hs
--- a/src/Data/Diverse/Lens/Many.hs
+++ b/src/Data/Diverse/Lens/Many.hs
@@ -27,14 +27,13 @@
     , projectL'
     , projectN
     , projectN'
-
     ) where
 
 import Control.Lens
-import Data.Proxy
 import Data.Tagged
 import Data.Diverse.Many
 import Data.Diverse.TypeLevel
+import Data.Proxy
 
 -- | @_Many = iso fromMany toMany@
 _Many :: IsMany t xs a => Iso' (Many xs) (t xs a)
diff --git a/src/Data/Diverse/Lens/Which.hs b/src/Data/Diverse/Lens/Which.hs
--- a/src/Data/Diverse/Lens/Which.hs
+++ b/src/Data/Diverse/Lens/Which.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
 {-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE TypeFamilies #-}
 
 module Data.Diverse.Lens.Which (
       -- * Single type
@@ -14,7 +15,6 @@
     , inject
     , injectL
     , injectN
-
     ) where
 
 import Control.Lens
diff --git a/src/Data/Diverse/Profunctor.hs b/src/Data/Diverse/Profunctor.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Diverse/Profunctor.hs
@@ -0,0 +1,11 @@
+module Data.Diverse.Profunctor (
+    -- * Re-export "Data.Diverse" for convenience
+      module Data.Diverse
+    -- * Combinators analogous to Profunctor Strong and Choice
+    , module Data.Diverse.Profunctor.Many
+    , module Data.Diverse.Profunctor.Which
+    ) where
+
+import Data.Diverse
+import Data.Diverse.Profunctor.Many
+import Data.Diverse.Profunctor.Which
diff --git a/src/Data/Diverse/Profunctor/Many.hs b/src/Data/Diverse/Profunctor/Many.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Diverse/Profunctor/Many.hs
@@ -0,0 +1,98 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Data.Diverse.Profunctor.Many (
+      -- * Combinators similar to Profunctor Strong
+      itemized
+    , itemized'
+    , projected
+    , (*&&*)
+    , (>&&>)
+    , (<&&<)
+    ) where
+
+import qualified Control.Category as C
+import Control.Arrow
+import Control.Lens
+import Data.Diverse.Many
+import Data.Diverse.TypeLevel
+import Data.Profunctor
+import Data.Proxy
+
+-- | Like 'Strong' or 'Arrow' but lifting into 'Many'
+itemized
+    :: forall a' w a b. ( Profunctor w
+       , Strong w
+       , UniqueMember a a'
+       , UniqueMember b (Replace a b a')
+       )
+    => w a b -> w (Many a') (Many (Replace a b a'))
+itemized w = dimap (\c -> (fetch c, c)) (\(b, c) -> replace' (Proxy @a) c b) (first' w)
+
+-- | Like 'Strong' or 'Arrow' but lifting into 'Many' of one type
+itemized' :: Profunctor w => w a b -> w (Many '[a]) (Many '[b])
+itemized' w = dimap fetch single w
+
+-- | Like 'Strong' or 'Arrow' but lifting from a 'Many' to a 'Many' of another type
+projected
+    :: forall a' proxy w a b. ( Profunctor w
+       , Strong w
+       , Select a a'
+       , Amend' a b a'
+       )
+    => proxy a' -> w (Many a) (Many b) -> w (Many a') (Many (Replaces a b a'))
+projected _ w = dimap (\c -> (select c, c)) (\(b, c) -> amend' (Proxy @a) c b) (first' w)
+
+-- | Split the input between the two argument arrows and combine their output.
+-- The type of the resultant input is a 'Many' of all the unique types in the argument arrows' inputs,
+-- The type of the resultant output is a concatenated 'Many' of the arguments arrows' outputs.
+-- Analogous to a 'Many' combination of both of 'Control.Arrow.***' and 'Control.Arrow.&&&'.
+-- It is a compile error if the types are not distinct in each of the argument arrow inputs.
+(*&&*)
+    :: forall w a1 b1 a2 b2. ( C.Category w
+       , Profunctor w
+       , Strong w
+       , Select a1 (AppendUnique a1 a2)
+       , Select a2 (AppendUnique a1 a2)
+       )
+    => w (Many a1) (Many b1)
+    -> w (Many a2) (Many b2)
+    -> w (Many (AppendUnique a1 a2)) (Many (Append b1 b2))
+x *&&* y = rmap (uncurry (/./)) (lmap (select @a1 &&& select @a2) (first' x) C.>>> second' y)
+infixr 3 *&&* -- like ***
+
+-- | 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 b1 a2 b2.
+       ( C.Category w
+       , Profunctor w
+       , Strong w
+       , Select (Complement b1 a2) b1
+       , Select a2 b1
+       )
+    => w a (Many b1)
+    -> w (Many a2) (Many b2)
+    -> w a (Many (Append (Complement b1 a2) b2))
+x >&&> y = rmap (uncurry (/./)) (rmap (select @(Complement b1 a2) &&& select @a2) x C.>>> (second' y))
+infixr 3 >&&> -- like ***
+
+-- | right-to-left version of '(>&&>)'
+(<&&<) ::
+       ( C.Category w
+       , Profunctor w
+       , Strong w
+       , Select (Complement b1 a2) b1
+       , Select a2 b1
+       )
+    => w (Many a2) (Many b2)
+    -> w a (Many b1)
+    -> w a (Many (Append (Complement b1 a2) b2))
+(<&&<) = flip (>&&>)
+infixl 2 <&&< -- like >&&>
diff --git a/src/Data/Diverse/Profunctor/Which.hs b/src/Data/Diverse/Profunctor/Which.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Diverse/Profunctor/Which.hs
@@ -0,0 +1,118 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Data.Diverse.Profunctor.Which (
+      -- * Combinators similar to Profunctor Choice
+      faceted
+    , faceted'
+    , injected
+    , (+||+)
+    , (>||>)
+    , (<||<)
+    ) where
+
+import qualified Control.Category as C
+import Control.Lens
+import Data.Diverse.Which
+import Data.Diverse.TypeLevel
+import Data.Proxy
+
+-- | Like 'Choice' or 'ArrowChoice' but lifting into 'Which'
+faceted
+    :: ( Profunctor w
+       , Choice w
+       , UniqueMember a a'
+       , UniqueMember b b'
+       , Diversify (Complement a' '[a]) b'
+       )
+    => w a b -> w (Which a') (Which b')
+faceted w = dimap trial (either diversify pick) (right' w)
+
+-- | Like 'Choice' or 'ArrowChoice' but lifting into 'Which' of one type
+faceted' :: (Profunctor w, Choice w) => w a b -> w (Which '[a]) (Which '[b])
+faceted' w = dimap trial (either impossible pick) (right' w)
+
+-- | Like 'Choice' or 'ArrowChoice' but lifting from 'Which' into another type of 'Which'
+-- NB. It is a compile error if all of the input types in the second arrow @a@
+-- is not the output types of the first arrow.
+-- This prevents surprising behaviour where the second arrow is ignored.
+injected
+    :: ( Profunctor w
+       , Choice w
+       , Reinterpret a a'
+       , Diversify b (AppendUnique (Complement a' a) b)
+       , Diversify (Complement a' a) (AppendUnique (Complement a' a) b)
+       -- extra contraint to prevent surprises (see comment above)
+       , Complement a a' ~ '[]
+       )
+    => proxy a'
+    -> w (Which a) (Which b)
+    -> w (Which a') (Which (AppendUnique (Complement a' a) b))
+injected _ w = dimap reinterpret (either diversify diversify) (right' w)
+
+-- | Split the input between the two argument arrows, retagging and merging their outputs.
+-- The output is merged into a 'Which' of unique types.
+-- Analogous to a 'Which' combination of both 'Control.Arrow.+++' and 'Control.Arrow.|||'.
+-- It is a compile error if the types are not distinct after 'Append'ing both argument arrows inputs.
+-- This is to prevent accidently processing an input type twice.
+-- The compile error will be due to @(Append a1 a2)@ which will not satisfy
+-- @UniqueMember@ constraints in 'Reinterpret'.
+(+||+)
+    :: forall w a1 b1 a2 b2.
+       ( C.Category w
+       , Profunctor w
+       , Choice w
+       , Reinterpret a2 (Append a1 a2)
+       , a1 ~ Complement (Append a1 a2) a2
+       , Diversify b1 (AppendUnique b1 b2)
+       , Diversify b2 (AppendUnique b1 b2)
+       )
+    => w (Which a1) (Which b1)
+    -> w (Which a2) (Which b2)
+    -> w (Which (Append a1 a2)) (Which (AppendUnique b1 b2))
+x +||+ y =
+    rmap
+        (either diversify diversify)
+        (lmap (reinterpret @a2 @(Append a1 a2)) (left' x) C.>>> right' y)
+infixr 2 +||+ -- like +++
+
+-- | 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 @Complement c b ~ '[]@ constraint.
+(>||>)
+    :: forall w a b c d.
+       ( C.Category w
+       , Profunctor w
+       , Choice w
+       , Reinterpret c b
+       , Diversify d (AppendUnique (Complement b c) d)
+       , Diversify (Complement b c) (AppendUnique (Complement b c) d)
+       , Complement c b ~ '[])
+    => w a (Which b)
+    -> w (Which c) (Which d)
+    -> w a (Which (AppendUnique (Complement b c) d))
+(>||>) hdl1 hdl2 = hdl1 C.>>> injected (Proxy @b) hdl2
+infixr 2 >||> -- like +||+
+
+-- | right-to-left version of '(>||>)'
+(<||<)
+    :: ( C.Category w
+       , Profunctor w
+       , Choice w
+       , Reinterpret c b
+       , Diversify d (AppendUnique (Complement b c) d)
+       , Diversify (Complement b c) (AppendUnique (Complement b c) d)
+       , Complement c b ~ '[])
+    => w (Which c) (Which d)
+    -> w a (Which b)
+    -> w a (Which (AppendUnique (Complement b c) d))
+(<||<) = flip (>||>)
+infixl 2 <||< -- like >||>
