1-- |
2-- Module: Optics.Each
3-- Description: An 'IxTraversal' for 'each' element of a (potentially monomorphic) container.
4--
5-- This module defines the 'Each' class, which provides an 'IxTraversal' that
6-- extracts 'each' element of a (potentially monomorphic) container.
7--
8{-# LANGUAGE UndecidableInstances #-}
9{-# OPTIONS_GHC -fno-warn-orphans #-}
10module Optics.Each
11  (
12  -- * Each
13    Each(..)
14  ) where
15
16import Data.ByteString as SB
17import Data.ByteString.Lazy as LB
18import Data.HashMap.Lazy as HashMap
19import Data.Int
20import Data.Text as ST
21import Data.Text.Lazy as LT
22import Data.Text.Optics (text)
23import Data.Vector.Generic.Optics (vectorTraverse)
24import Data.Vector.Primitive (Prim)
25import Data.Vector.Storable (Storable)
26import Data.Vector.Unboxed (Unbox)
27import Data.Word
28import qualified Data.Vector as V
29import qualified Data.Vector.Primitive as VP
30import qualified Data.Vector.Storable as VS
31import qualified Data.Vector.Unboxed as VU
32
33import Optics.Core
34import Optics.Indexed ()
35import Optics.Extra.Internal.ByteString
36
37-- Extra instances
38
39-- | @'each' :: 'IxTraversal' k ('HashMap' k a) ('HashMap' k b) a b@
40instance k ~ k' => Each k (HashMap k a) (HashMap k' b) a b where
41  -- traverseWithKey has best performance for all flavours for some reason.
42  each = itraversalVL HashMap.traverseWithKey
43  {-# INLINE[1] each #-}
44
45-- | @'each' :: 'IxTraversal' Int ('V.Vector' a) ('V.Vector' b) a b@
46instance Each Int (V.Vector a) (V.Vector b) a b where
47  each = vectorTraverse
48  {-# INLINE[1] each #-}
49
50-- | @'each' :: ('Prim' a, 'Prim' b) => 'IxTraversal' Int ('Prim.Vector' a)
51-- ('Prim.Vector' b) a b@
52instance (Prim a, Prim b) => Each Int (VP.Vector a) (VP.Vector b) a b where
53  each = vectorTraverse
54  {-# INLINE[1] each #-}
55
56-- | @'each' :: ('Storable' a, 'Storable' b) => 'IxTraversal' 'Int' ('VS.Vector'
57-- a) ('VS.Vector' b) a b@
58instance (Storable a, Storable b) => Each Int (VS.Vector a) (VS.Vector b) a b where
59  each = vectorTraverse
60  {-# INLINE[1] each #-}
61
62-- | @'each' :: ('Unbox' a, 'Unbox' b) => 'IxTraversal' 'Int' ('VU.Vector' a)
63-- ('VU.Vector' b) a b@
64instance (Unbox a, Unbox b ) => Each Int (VU.Vector a) (VU.Vector b) a b where
65  each = vectorTraverse
66  {-# INLINE[1] each #-}
67
68-- | @'each' :: 'IxTraversal' 'Int' 'ST.Text' 'ST.Text' 'Char' 'Char'@
69instance (a ~ Char, b ~ Char) => Each Int ST.Text ST.Text a b where
70  each = text
71  {-# INLINE[1] each #-}
72
73-- | @'each' :: 'IxTraversal' 'Int64' 'LT.Text' 'LT.Text' 'Char' 'Char'@
74instance (a ~ Char, b ~ Char) => Each Int LT.Text LT.Text a b where
75  each = text
76  {-# INLINE[1] each #-}
77
78-- | @'each' :: 'IxTraversal' 'Int' 'SB.ByteString' 'SB.ByteString' 'Word8'
79-- 'Word8'@
80instance (a ~ Word8, b ~ Word8) => Each Int64 SB.ByteString SB.ByteString a b where
81  each = traversedStrictTree
82  {-# INLINE[1] each #-}
83
84-- | @'each' :: 'IxTraversal' 'Int64' 'LB.ByteString' 'LB.ByteString' 'Word8'
85-- 'Word8'@
86instance (a ~ Word8, b ~ Word8) => Each Int64 LB.ByteString LB.ByteString a b where
87  each = traversedLazy
88  {-# INLINE[1] each #-}
89