{-# LANGUAGE Rank2Types #-}
-- | This module contains lenses and traversals for common structures in Haskell.
-- It also contains the combinators for lenses and traversals.
module Lens.Family2.Stock (
-- * Lens Combinators
    Stock.choosing
  , Stock.alongside
  , Stock.beside
-- * Stock Lenses
  , _1, _2
  , chosen
  , ix
  , at, intAt
  , contains, intContains
-- * Stock Traversals
  , both
  , _Left, _Right
  , _Just, _Nothing
  , ignored
-- * Stock SECs
  , mapped
-- * Types
  , Stock.AlongsideLeft, Stock.AlongsideRight
-- * Re-exports
  , Lens, Lens'
  , Traversal, Traversal'
  , Setter
  , Stock.LensLike, Stock.LensLike'
  , Stock.Applicative, Stock.Identical
  ) where

import qualified Lens.Family.Stock as Stock
import Lens.Family2 ( Lens, Lens'
                    , Traversal, Traversal'
                    , Setter
                    )
import qualified Data.Map as Map
import qualified Data.IntMap as IntMap
import qualified Data.Set as Set
import qualified Data.IntSet as IntSet

-- | Lens on the first element of a pair.
_1 :: Lens (a, b) (a', b) a a'
_1 = Stock._1

-- | Lens on the second element of a pair.
_2 :: Lens (a, b) (a, b') b b'
_2 = Stock._2

-- | Lens on the Left or Right element of an ('Either' a a).
chosen :: Lens (Either a a) (Either b b) a b
chosen = Stock.chosen

-- | Lens on a given point of a function.
ix :: Eq k => k -> Lens' (k -> v) v
ix = Stock.ix

-- | Lens on a given point of a 'Map.Map'.
at :: Ord k => k -> Lens' (Map.Map k v) (Maybe v)
at = Stock.at

-- | Lens on a given point of a 'IntMap.IntMap'.
intAt :: Int -> Lens' (IntMap.IntMap v) (Maybe v)
intAt = Stock.intAt

-- | Lens on a given point of a 'Set.Set'.
contains :: Ord k => k -> Lens' (Set.Set k) Bool
contains = Stock.contains

-- | Lens on a given point of a 'IntSet.IntSet'.
intContains :: Int -> Lens' IntSet.IntSet Bool
intContains = Stock.intContains

-- | Traversal on the 'Left' element of an 'Either'.
_Left :: Traversal (Either a b) (Either a' b) a a'
_Left = Stock._Left

-- | Traversal on the 'Right' element of an 'Either'.
_Right :: Traversal (Either a b) (Either a b') b b'
_Right = Stock._Right

-- | Traversal on the 'Just' element of a 'Maybe'.
_Just :: Traversal (Maybe a) (Maybe a') a a'
_Just = Stock._Just

-- | Traversal on the 'Nothing' element of a 'Maybe'.
_Nothing :: Traversal' (Maybe a) ()
_Nothing = Stock._Nothing

-- | Traversals on both elements of a pair @(a,a)@.
both :: Traversal (a,a) (b,b) a b
both = Stock.both

-- | The empty traveral on any type.
ignored :: Traversal a a b b'
ignored = Stock.ignored

-- | An SEC referencing the parameter of a functor.
mapped :: Functor f => Setter (f a) (f a') a a'
mapped = Stock.mapped