{-# language ScopedTypeVariables #-}
{-# language RankNTypes #-}
module Control.Lens.Selection
  ( selected
  , unselected
  , inverted
  , unwrapped
  ) where

import Data.Functor.Selection
import Data.Bitraversable

type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t
type Traversal' s a = Traversal s s a a

-- | Traversal over selected elements
--
-- @'selected' = 'traverse'@
selected :: (Traversable f) => Traversal (Selection f b a) (Selection f b a') a a'
selected :: Traversal (Selection f b a) (Selection f b a') a a'
selected = (a -> f a') -> Selection f b a -> f (Selection f b a')
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse

-- | Traversal over unselected elements
--
-- @'unselected' = 'inverting' . 'selected'@
unselected :: (Traversable f) => Traversal (Selection f b a) (Selection f b' a) b b'
unselected :: Traversal (Selection f b a) (Selection f b' a) b b'
unselected = (Selection f a b -> f (Selection f a b'))
-> Selection f b a -> f (Selection f b' a)
forall (f :: * -> *) b a b' a'.
Functor f =>
Traversal
  (Selection f b a)
  (Selection f b' a')
  (Selection f a b)
  (Selection f a' b')
inverted ((Selection f a b -> f (Selection f a b'))
 -> Selection f b a -> f (Selection f b' a))
-> ((b -> f b') -> Selection f a b -> f (Selection f a b'))
-> (b -> f b')
-> Selection f b a
-> f (Selection f b' a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b -> f b') -> Selection f a b -> f (Selection f a b')
forall (f :: * -> *) b a a'.
Traversable f =>
Traversal (Selection f b a) (Selection f b a') a a'
selected

-- | Traversal which inverts the current selection
--
-- This is provided as a Traversal to avoid adding a 'profunctors' dependency.
-- You can write the corresponding iso if you wish:
--
-- @
-- 'inverting' = iso 'invertSelection' 'invertSelection'
-- @
inverted :: (Functor f) => Traversal (Selection f b a) (Selection f b' a') (Selection f a b) (Selection f a' b')
inverted :: Traversal
  (Selection f b a)
  (Selection f b' a')
  (Selection f a b)
  (Selection f a' b')
inverted f :: Selection f a b -> f (Selection f a' b')
f s :: Selection f b a
s = Selection f a' b' -> Selection f b' a'
forall (f :: * -> *) b a.
Functor f =>
Selection f b a -> Selection f a b
invertSelection (Selection f a' b' -> Selection f b' a')
-> f (Selection f a' b') -> f (Selection f b' a')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Selection f a b -> f (Selection f a' b')
f (Selection f b a -> Selection f a b
forall (f :: * -> *) b a.
Functor f =>
Selection f b a -> Selection f a b
invertSelection Selection f b a
s)

-- | Traversal which exposes the underlying functor representation
--
-- This is provided as a Traversal to avoid adding a 'profunctors' dependency.
-- You can write the corresponding iso if you wish:
--
-- @'unwrapping' = iso 'unwrapSelection' 'wrapSelection'@
unwrapped :: Traversal (Selection f b a) (Selection f b' a') (f (Either b a)) (f (Either b' a'))
unwrapped :: (f (Either b a) -> f (f (Either b' a')))
-> Selection f b a -> f (Selection f b' a')
unwrapped f :: f (Either b a) -> f (f (Either b' a'))
f s :: Selection f b a
s = f (Either b' a') -> Selection f b' a'
forall (f :: * -> *) b a. f (Either b a) -> Selection f b a
Selection (f (Either b' a') -> Selection f b' a')
-> f (f (Either b' a')) -> f (Selection f b' a')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f (Either b a) -> f (f (Either b' a'))
f (Selection f b a -> f (Either b a)
forall (f :: * -> *) b a. Selection f b a -> f (Either b a)
unwrapSelection Selection f b a
s)