-- | -- Module: Optics.Each.Core -- Description: An 'IxTraversal' for each element of a (potentially monomorphic) container. -- -- This module defines the 'Each' class, which provides an 'IxTraversal' that -- extracts 'each' element of a (potentially monomorphic) container. -- -- Note that orphan instances for this class are defined in the @Optics.Each@ -- module from @optics-extra@, so if you are not simply depending on @optics@ -- you may wish to import that module instead. -- {-# LANGUAGE UndecidableInstances #-} module Optics.Each.Core ( -- * Each Each(..) ) where import Data.Complex (Complex (..)) import Data.Functor.Identity (Identity (..)) import Data.List.NonEmpty (NonEmpty (..)) import Data.Tree (Tree (..)) import Data.Ix (Ix) import Data.Array (Array) import Data.IntMap (IntMap) import qualified Data.IntMap as IntMap import Data.Map (Map) import qualified Data.Map as Map import Data.Sequence (Seq) import Optics.IxLens import Optics.IxTraversal import Optics.Optic -- | Extract 'each' element of a (potentially monomorphic) container. -- -- >>> over each (*10) (1,2,3) -- (10,20,30) -- -- >>> iover each (\i a -> a*10 + succ i) (1,2,3) -- (11,22,33) -- class Each i s t a b | s -> i a, t -> i b, s b -> t, t a -> s where each :: IxTraversal i s t a b default each :: (TraversableWithIndex i g, s ~ g a, t ~ g b) => IxTraversal i s t a b each = itraversed {-# INLINE[1] each #-} -- | @'each' :: 'IxTraversal' 'Int' (a, a) (b, b) a b@ instance (a ~ a1, b ~ b1 ) => Each Int (a, a1) (b, b1) a b where each = itraversalVL $ \f (a0, a1) -> (,) <$> f 0 a0 <*> f 1 a1 {-# INLINE[1] each #-} -- | @'each' :: 'IxTraversal' 'Int' (a, a, a) (b, b, b) a b@ instance (a ~ a1, a ~ a2, b ~ b1, b ~ b2 ) => Each Int (a, a1, a2) (b, b1, b2) a b where each = itraversalVL $ \f (a0, a1, a2) -> (,,) <$> f 0 a0 <*> f 1 a1 <*> f 2 a2 {-# INLINE[1] each #-} -- | @'each' :: 'IxTraversal' 'Int' (a, a, a, a) (b, b, b, b) a b@ instance (a ~ a1, a ~ a2, a ~ a3, b ~ b1, b ~ b2, b ~ b3 ) => Each Int (a, a1, a2, a3) (b, b1, b2, b3) a b where each = itraversalVL $ \f (a0, a1, a2, a3) -> (,,,) <$> f 0 a0 <*> f 1 a1 <*> f 2 a2 <*> f 3 a3 {-# INLINE[1] each #-} -- | @'each' :: 'IxTraversal' 'Int' (a, a, a, a, a) (b, b, b, b, b) a b@ instance (a ~ a1, a ~ a2, a ~ a3, a ~ a4, b ~ b1, b ~ b2, b ~ b3, b ~ b4 ) => Each Int (a, a1, a2, a3, a4) (b, b1, b2, b3, b4) a b where each = itraversalVL $ \f (a0, a1, a2, a3, a4) -> (,,,,) <$> f 0 a0 <*> f 1 a1 <*> f 2 a2 <*> f 3 a3 <*> f 4 a4 {-# INLINE[1] each #-} -- | @'each' :: 'IxTraversal' 'Int' (a, a, a, a, a, a) (b, b, b, b, b, b) a b@ instance (a ~ a1, a ~ a2, a ~ a3, a ~ a4, a ~ a5, b ~ b1, b ~ b2, b ~ b3, b ~ b4, b ~ b5 ) => Each Int (a, a1, a2, a3, a4, a5) (b, b1, b2, b3, b4, b5) a b where each = itraversalVL $ \f (a0, a1, a2, a3, a4, a5) -> (,,,,,) <$> f 0 a0 <*> f 1 a1 <*> f 2 a2 <*> f 3 a3 <*> f 4 a4 <*> f 5 a5 {-# INLINE[1] each #-} -- | @'each' :: 'IxTraversal' 'Int' (a, a, a, a, a, a, a) (b, b, b, b, b, b, b) -- a b@ instance (a ~ a1, a ~ a2, a ~ a3, a ~ a4, a ~ a5, a ~ a6, b ~ b1, b ~ b2, b ~ b3, b ~ b4, b ~ b5, b ~ b6 ) => Each Int (a, a1, a2, a3, a4, a5, a6) (b, b1, b2, b3, b4, b5, b6) a b where each = itraversalVL $ \f (a0, a1, a2, a3, a4, a5, a6) -> (,,,,,,) <$> f 0 a0 <*> f 1 a1 <*> f 2 a2 <*> f 3 a3 <*> f 4 a4 <*> f 5 a5 <*> f 6 a6 {-# INLINE[1] each #-} -- | @'each' :: 'IxTraversal' 'Int' (a, a, a, a, a, a, a, a) (b, b, b, b, b, b, -- b, b) a b@ instance (a ~ a1, a ~ a2, a ~ a3, a ~ a4, a ~ a5, a ~ a6, a ~ a7, b ~ b1, b ~ b2, b ~ b3, b ~ b4, b ~ b5, b ~ b6, b ~ b7 ) => Each Int (a, a1, a2, a3, a4, a5, a6, a7) (b, b1, b2, b3, b4, b5, b6, b7) a b where each = itraversalVL $ \f (a0, a1, a2, a3, a4, a5, a6, a7) -> (,,,,,,,) <$> f 0 a0 <*> f 1 a1 <*> f 2 a2 <*> f 3 a3 <*> f 4 a4 <*> f 5 a5 <*> f 6 a6 <*> f 7 a7 {-# INLINE[1] each #-} -- | @'each' :: 'IxTraversal' 'Int' (a, a, a, a, a, a, a, a, a) (b, b, b, b, b, -- b, b, b, b) a b@ instance (a ~ a1, a ~ a2, a ~ a3, a ~ a4, a ~ a5, a ~ a6, a ~ a7, a ~ a8, b ~ b1, b ~ b2, b ~ b3, b ~ b4, b ~ b5, b ~ b6, b ~ b7, b ~ b8 ) => Each Int (a, a1, a2, a3, a4, a5, a6, a7, a8) (b, b1, b2, b3, b4, b5, b6, b7, b8) a b where each = itraversalVL $ \f (a0, a1, a2, a3, a4, a5, a6, a7, a8) -> (,,,,,,,,) <$> f 0 a0 <*> f 1 a1 <*> f 2 a2 <*> f 3 a3 <*> f 4 a4 <*> f 5 a5 <*> f 6 a6 <*> f 7 a7 <*> f 8 a8 {-# INLINE[1] each #-} -- | @'each' :: 'IxTraversal' 'Int' (a, a, a, a, a, a, a, a, a, a) (b, b, b, b, -- b, b, b, b, b, b) a b@ instance (a ~ a1, a ~ a2, a ~ a3, a ~ a4, a ~ a5, a ~ a6, a ~ a7, a ~ a8, a ~ a9, b ~ b1, b ~ b2, b ~ b3, b ~ b4, b ~ b5, b ~ b6, b ~ b7, b ~ b8, b ~ b9 ) => Each Int (a, a1, a2, a3, a4, a5, a6, a7, a8, a9) (b, b1, b2, b3, b4, b5, b6, b7, b8, b9) a b where each = itraversalVL $ \f (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) -> (,,,,,,,,,) <$> f 0 a0 <*> f 1 a1 <*> f 2 a2 <*> f 3 a3 <*> f 4 a4 <*> f 5 a5 <*> f 6 a6 <*> f 7 a7 <*> f 8 a8 <*> f 9 a9 {-# INLINE[1] each #-} -- | @'each' :: 'IxTraversal' ('Either' () ()) ('Either' a a) ('Either' b b) a -- b@ instance (a ~ a', b ~ b' ) => Each (Either () ()) (Either a a') (Either b b') a b where each = castOptic chosen {-# INLINE[1] each #-} -- | @'each' :: ('RealFloat' a, 'RealFloat' b) => 'IxTraversal' (Either () ()) -- ('Complex' a) ('Complex' b) a b@ instance Each (Either () ()) (Complex a) (Complex b) a b where each = itraversalVL $ \f (a :+ b) -> (:+) <$> f (Left ()) a <*> f (Right ()) b {-# INLINE[1] each #-} -- | @'each' :: 'IxTraversal' k ('Map' k a) ('Map' k b) a b@ instance k ~ k' => Each k (Map k a) (Map k' b) a b where -- traverseWithKey has best performance for all flavours for some reason. each = itraversalVL Map.traverseWithKey {-# INLINE[1] each #-} -- | @'each' :: 'IxTraversal' 'Int' ('IntMap' a) ('IntMap' b) a b@ instance Each Int (IntMap a) (IntMap b) a b where -- traverseWithKey has best performance for all flavours for some reason. each = itraversalVL IntMap.traverseWithKey {-# INLINE[1] each #-} -- | @'each' :: 'IxTraversal' 'Int' [a] [b] a b@ instance Each Int [a] [b] a b -- | @'each' :: 'IxTraversal' 'Int' (NonEmpty a) (NonEmpty b) a b@ instance Each Int (NonEmpty a) (NonEmpty b) a b -- | @'each' :: 'IxTraversal' () ('Identity' a) ('Identity' b) a b@ instance Each () (Identity a) (Identity b) a b -- | @'each' :: 'IxTraversal' () ('Maybe' a) ('Maybe' b) a b@ instance Each () (Maybe a) (Maybe b) a b -- | @'each' :: 'IxTraversal' 'Int' ('Seq' a) ('Seq' b) a b@ instance Each Int (Seq a) (Seq b) a b -- | @'each' :: 'IxTraversal' [Int] ('Tree' a) ('Tree' b) a b@ instance Each [Int] (Tree a) (Tree b) a b -- | @'each' :: 'Ix' i => 'IxTraversal' i ('Array' i a) ('Array' i b) a b@ instance (Ix i, i ~ j) => Each i (Array i a) (Array j b) a b -- $setup -- >>> import Optics.Core